Compare commits

...

108 Commits

Author SHA1 Message Date
4df57136e9 Version 1.81 2021-02-10 21:16:58 +01:00
647a308ad3 Backends: GLFW: Add ImGui_ImplGlfw_InitForOther() instead of ImGui_ImplGlfw_InitForWebGPU() so it can be used for e.g. DX11. (#3632)
Amend dff0044
2021-02-10 17:27:33 +01:00
f14042ca78 Viewports Added ImGui::GetMainViewport() as a way to get the bounds and work area of the host display. (#3789, #1542)
Viewports: Backport a few constructs from 'docking' branch.
Viewports: Added ImGuiViewportFlags_IsPlatformWindow, ImGuiViewportFlags_IsPlatformMonitor, ImGuiViewportFlags_OwnedByApp (none of them were in docking branch yet). ImGuiViewportFlags_IsPlatformMonitor is merely there to convey future intent, not yet used.
Reduce uses of io.DisplaySize.
MainMenuBar: Backport work area handling code from 'docking' branch.
Metrics: Backported "Viewports" debug visualizer from 'docking' branch.
Demo: Rework 'Examples->Fullscreen Window'.
Demo: 'Simple Overlay' demo now moves under main menu-bar (if any) using GetMainViewport()'s work area.
2021-02-10 16:09:53 +01:00
3b4d3a9b73 Simplify CI scripts (#3764)
* Deps paths through https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-environment-variable
* Use heredocs for pasting source code
* Remove fetch-depth arg, it's the default
* Merge the `brew install`s, it's simpler and maybe even faster
2021-02-10 16:08:46 +01:00
56f7bdae99 ImDrawList: Clarified PathArcTo() need for a_min <= a_max with an assert. Fixed PathArcToFast() handling of a_min > a_max. 2021-02-08 16:37:51 +01:00
03038df1cc ImDrawList: fix divide by zero (for which result was unused but triggering on some archs/setup) added by f144c67676 (#3738) 2021-02-08 14:03:24 +01:00
b898281e3c Demo: Added 'Examples->Fullscreen Window' demo. (#3789) + repack and zero-clear ImDrawData. 2021-02-05 15:44:10 +01:00
58a0a7058c Backends: Using SetTexID() consistently instead of assigning to ->TexID. May make the later obsolete eventually. 2021-02-03 18:30:26 +01:00
82a9b599ab Backend: webgpu: Fixes blending issue on Chrome 90+ and makes backend forward compatible with Emscripten 2.0.14 (#3632, #3770) 2021-02-03 16:35:11 +01:00
03d74a293d ListBox: renamed ListBoxHeader>BeginListBox, ListBoxFooter>EndListBox. Added demo bits. 2021-02-03 16:33:22 +01:00
6f6d4e0b70 ListBoxHeader: In version taking height in number of items, made vertical padding consistent regardless of if (items_count <= height_in_items) or not.
Demo: Tweaks.
2021-02-03 15:07:14 +01:00
e5cbf60def ListBox: tweaked default height calculation. simplifying code internally (rework passing of full rect). Should have no visible side-effects + misc comments. 2021-02-03 14:54:56 +01:00
90a518c501 Fixed typos (#3782) 2021-02-03 12:37:32 +01:00
d1a9efdd8f InputText: Fixed slightly off ScrollX tracking, noticeable with large values of FramePadding.x. Multiline: Fixed padding/cliprect not matching single-line version. (#3781)
Fixed FramePadding.y worth of vertical offset when aiming with mouse.
2021-02-02 16:30:57 +01:00
a3f0393351 Menus: Fixed an issue with child-menu auto-sizing (issue introduced by 6af92b0) (#3779) 2021-02-02 13:06:51 +01:00
929563c3a7 Log/Capture: Fixes for handling \n in strings. Improve the look of various widgets. Added LogSetNextTextDecoration helper. Fixup/amend dbaf74d75.
For now removed LogRenderedTextNewLine() - it is eventually desirable but currently carries too much ambiguities, so reverted until we have a better system and test suite.
2021-02-02 12:29:58 +01:00
dbaf74d758 Log/Capture: Fix various new line/spacing issue by using same render text position when there are both RenderText and LogRenderedText call in widget code.
Also Buttons are now enclosed in bracket
2021-02-02 09:38:57 +01:00
9d576a96a5 Tables: added internal TableSetColumnEnabled() helper. Comments. 2021-02-02 09:23:40 +01:00
4dec436161 SliderInt: Fixed click/drag when v_min==v_max from setting the value to zero. (#3774) 2021-02-01 17:34:16 +01:00
24be26e00e imgui_freetype: Add support for colored glyphs. Font: add support for untinted glyphs (#3369)
Amend 9499afd with missing static inline.
2021-02-01 16:32:26 +01:00
24aa6654df imgui_freetype: add support for colored glyphs with ImGuiFreeTypeBuilderFlags_LoadColor (#3369)
(squashed 4 commits)
2021-02-01 16:32:23 +01:00
4622fa4b66 Fonts: Fixed CalcTextSize() width rounding so it behaves more like a ceil. (#3776)
his is in order for text wrapping to have enough space when provided width precisely calculated with CalcTextSize().x. Amend 7b0bf230.
Note that the rounding of either positions and widths are technically undesirable (e.g. #3437, #791) but variety of code is currently on it so we are first fixing current behavior before we'll eventually change it.
2021-02-01 12:49:18 +01:00
9499afdf5e imgui_freetype: clarify breaking changes, and add BuildFontAtlas() to be consistent with planned obsolescence. Rename mislabelled internal helper. Demo: clarify labels in nested table demo. (#3765) 2021-01-28 20:53:53 +01:00
dff0044d4e Backends, Examples: Added support for WebGPU and corresponding example. Amend 5853fbd (#3632) 2021-01-28 15:40:31 +01:00
5853fbd68b Backends, Examples: Added support for WebGPU and corresponding example (#3632)
(Squashed 11 commits)
2021-01-28 11:37:46 +01:00
6487860aae Backends: Vulkan: Rework support for custom function/symbol loader (#3759, #3227), add ImGui_ImplVulkan_LoadFunctions (amend 6001c54)
Making it a separate function allows to use/test this with our examples or any code using the VulkanH helper called before ImGui_ImplVulkan_Init()
2021-01-27 13:43:49 +01:00
6001c54598 Backends: Vulkan: Support for custom function/symbol loader (#3759, #3227)
- It adds an optional feature to support dynamic linkage of Vulkan instead of using default linkage.
 - It is now possible to have several potentially working implementation and whenever the Vulkan library was available it can work.
2021-01-27 12:54:51 +01:00
066406b9be Backends: OSX: Fix mouse position not being reported when mouse buttons other than left one are down. (#3762)
# Conflicts:
#	docs/CHANGELOG.txt
2021-01-27 12:44:42 +01:00
e28b51786e Tables: Fixed PopItemWidth() or multi-components items not restoring per-colum ItemWidth correctly. (#3760) rework local stacks to facilitate modifying current value without altering the stack.
May consider doing the same for ItemFlags and moving to g.ItemFlags...
2021-01-27 12:35:57 +01:00
3867c6c5f0 Fonts: (Breaking) Rename ImGuiFreeType:: flags to ImGuiFreeTypeBuilderFlags_XXX. Remove ImGuiFreeType::BuildFontAtlas() flags. Rename ImFontConfig::RasterizerFlags to FontBuilderFlags. Add ImFontBuilderIO (opaque). Amend 53d59f3 with a dozen of small fixes. 2021-01-26 17:25:09 +01:00
9417acc20f Fonts: if IMGUI_ENABLE_FREETYPE, use library by default for font rasterization
Also renamed IMGUI_DISABLE_STB_TRUETYPE to IMGUI_ENABLE_STB_TRUETYPE
2021-01-26 17:23:11 +01:00
6b32d0ebc7 Fixed minor title bar text clipping issue when FramePadding is small/zero and there are no close button in the window. (#3731) 2021-01-26 16:07:41 +01:00
a8d2d8ee97 Fixed uninitialized variable, amend f3f2578. (#3753) 2021-01-26 15:26:41 +01:00
f3f2578e8f Internals: Added context hook removal support (#3580, #3626, #3753) 2021-01-26 15:24:01 +01:00
f139846750 Backends: Win32: dynamically load XInput library (amends) (#3646, #3645, #3248, #2716) 2021-01-25 16:30:44 +01:00
633d1033af Backends: Win32: dynamically load XInput library (#3646, #3645, #3248, #2716) 2021-01-25 16:30:44 +01:00
2ed47e5822 Version 1.81 WIP 2021-01-25 16:30:44 +01:00
695a4bd1a9 Backends: Metal: Fixed texture storage mode when building on Mac Catalyst. (#3748) 2021-01-25 15:11:43 +01:00
f144c67676 ImDrawList: fixed AddCircle, AddCircleFilled buffer read overflow with (rad > 0.0f && rad < 1.0f && num_segments == 0). (#3738)
Amend 051ce076. Maximum cached count becomes 63 instead of 64.
2021-01-25 14:59:09 +01:00
58075c4414 Version 1.80 2021-01-21 20:36:18 +01:00
5178c3ce21 Tables: added ImGuiTableFlags_NoHostExtendX instead of using outer_size.x == 0.0f. Changed default outer_size to (0.0f, 0.0f). (#3605) 2021-01-21 16:20:31 +01:00
3b409d2b68 BeginChild: half-fixed child window name longer than 255 conflicting, merely raised the limit by using our shared large buffer. Comments. 2021-01-21 12:36:47 +01:00
6737037743 Tab Bar: fix 0ea4408 (#3414) 2021-01-20 19:35:10 +01:00
74b3b7cf58 Added experimental io.ConfigDragClickToInputText feature to enable turning DragXXX widgets into text input with a simple mouse click-release (without moving). (#3737)
+ Offset ImGuiTableColumnFlags values.
2021-01-20 19:18:03 +01:00
dc0f3d982c DragFloat, DragInt: very slightly increased mouse drag threshold + expressing it as a factor of default value + disabled experimental click-to-input on DragXXX functions. (#3737) 2021-01-20 18:36:21 +01:00
ae0d2dd614 Tables: rework submission of content size and ideal content size to outer window (now using IdealMaxPos introduced in 6af92b0).
See Tests suite "table_reported_size_outer".
2021-01-20 11:38:46 +01:00
f379dc28a3 ImBitArray: Rename ClearBits() to ClearAllBits() and add SetAllBits(). ImBitArraySetBitRange work on range [n..n2) instead of [n..n2] 2021-01-20 11:33:59 +01:00
3fef132f62 Tables: Clear scroll value when reactivating scroll. Assert when passing width/weight to TableSetupColumn() without an explicit sizing policy at either table or column label.
Clearing scroll was initially made desirable by tests exhibiting side effects but generally feels saner.
table->UserOuterSize is poorly used in this commit but will be by subsequent commits.
2021-01-19 21:55:28 +01:00
0ea4408fd4 Tab Bar: Requested ideal content size (for auto-fit) doesn't affect horizontal scrolling. Followup to afa01d8. (#3414)
+ minor Table rename
2021-01-15 22:52:47 +01:00
6af92b05bf Internals: Layout: maintain two content sizes, optionally writing to IdealMaxPos to distinguish used from ideal size, later is used for auto-fit. Unused in this commit, should be no-op. (#3414)
# Conflicts:
#	imgui.cpp
2021-01-15 22:52:42 +01:00
6470681d87 Use GitHub URL for Tracy Profiler. (#3721) 2021-01-15 22:39:27 +01:00
4d419d1211 Tables: fixed ColumnsAutoFitWidth for resizable fixed columns reporting ideal width. 2021-01-15 17:48:36 +01:00
3e712631da Tables: more moving of code in EndTable(), should have no side-effect. 2021-01-15 14:20:24 +01:00
626e3e2b3b Tables: fix reported inner-width for scrolling tables off by a small padding amount + moved code.
Makes not much difference for inner-scrolling but makes a difference when reported to outer-window.
2021-01-15 12:40:40 +01:00
3edfc042ff Tables: Internals: Renaming, tweaks preparing ahead for trickier changes (should be all no-op). 2021-01-15 11:11:16 +01:00
9e281c12a8 Tables: Fixed very small tables edge cases: inverted clip rect with freezing + scroll, missing borders. 2021-01-14 19:16:06 +01:00
b0db741770 Demo tweaks. Moved Tabs to Widgets section. Added to Tables demo. Increased version following 00b35c08. 2021-01-14 11:59:33 +01:00
00b35c081e Tables: (breaking) removed ImGuiTableColumnFlags_WidthAuto which now can be expressed as _Fixed + _NoResize. WidthRequest gets updated when RequestOutputMaskByIndex is set rather than Visible. 2021-01-13 18:42:02 +01:00
8cea3e3ed3 Tables: fixed border straying out of rect when using ImGuiTableFlags_NoBordersInBody with small height. 2021-01-13 12:24:55 +01:00
002ba1a69f Tables: comments, tweak. CollapsingHeader: comments. (#3715) 2021-01-13 10:07:59 +01:00
feaa7ea003 Examples: Emscripten: Amend ba636c5. (#3705) 2021-01-11 18:46:23 +01:00
0f14dd9781 Examples: Emscripten: Add 'make serve' helper, move output to web/ folder. (#3705) 2021-01-11 18:46:23 +01:00
31a2f0c164 Tables: fixed outer_width misreported to layout for use with SameLine when ScrollY is set but not ScrollX (#3704, #3414) 2021-01-11 11:31:50 +01:00
e485d451d1 Backends: DX12: improve Windows 7 compatibility (#3696)
- Attempt to load d3d12.dll from local D3D12On7 paths before falling back to System32
- Do not statically import D3D12SerializeRootSignature
2021-01-11 11:07:43 +01:00
36535514d5 Backends: DX12: Fix warning (#3706). Disable obsolete Tables enums, leave them commented out. Using _MSVC_LANG to enable offsetof() and static_assert() on VS2015.3+ 2021-01-11 10:54:52 +01:00
e18abe3619 Tables: (Breaking) Added ImGuiTableFlags_SizingFixedSame, ImGuiTableFlags_SizingStretchProp. Removed ImGuiTableFlags_SameWidths.
Simplified some code and clariffied that currently non-resizable = always revert to default (while waiting to untangle Fixed vs Auto and programmatic override not going through TableSetupColumn)
Whereas ImGuiTableFlags_SameWidths has some unusual handling of mixed Fixed/Stretch columns, we know treat them separately.
2021-01-08 18:40:52 +01:00
0e3ba37e6d Tables: Tidying up. Shuffle some columns fields to facilitate debugging + comments + demo tweaks + metrics highlight. 2021-01-08 18:32:18 +01:00
414f82254b Tables: (Breaking) rename ImGuiTableFlags_SizingPolicyFixed > ImGuiTableFlags_SizingFixedFit, ImGuiTableFlags_SizingPolicyStretch > ImGuiTableFlags_SizingStretchSame in prevision for new policies. 2021-01-08 18:10:55 +01:00
8b5f3798e0 Tables: Moved demo chunks. Made right-most non-resizable same-width column hidden to alleviate the issue where they are off by 1 pixel. 2021-01-07 17:11:18 +01:00
94a432275b ImDrawList: Internals: Add ability to scale anti-alias fringe. This enable users to keep geometry sharp while scaling vertex buffer content. 2021-01-05 16:34:11 +01:00
9bcf77eb81 Fixed using IsItemEdited() after Combo() not matching the return value from Combo(). (#2034) + fix some PVS warnings, fix typo, blanks.
Amend e28b1078
2021-01-04 19:15:20 +01:00
7d5d5711c2 Backends: OpenGL2, OpenGL3: Backup and restore GL_SHADE_MODAL, GL_STENCIL_TEST, clear GL_NORMAL_ARRAY. Comments., (#3671, #3668) 2021-01-03 17:01:54 +01:00
0a5f399805 Tables: Fix hiding column right after the frozen line. Fix hovering/resising column delimiter scrolled under frozen columns. (#3678) 2021-01-03 15:45:56 +01:00
1c1d3b7ab5 Added 64-bit variants of CheckboxFlags() in imgui_internal.h. Improve assert on mismatched ListBoxFooter() call. Fix FAQ index. (#3687) 2021-01-03 15:45:56 +01:00
8ec5daf35d Happy new year! 2021-01-03 15:42:32 +01:00
fa963b9aaf Inputs: Internal: added SetItemUsingMouseWheel() and mechanism to request mouse wheel for both HoveredId and ActiveId. (#2891)
Based on @kudaba PR.
2020-12-25 18:22:34 +01:00
eb88fee052 Tables: internal tidying up, calculate WidthAuto in first loop of layout + TableSetupColumn() with unspecified stretch weight leaves it at -1.0f (unset) rather than overrding default. Amend 3b3503e.
Both changes are intended to have no side-effects. Committed separately from upcoming commit for easier future bissecting.
Small demo fix.
2020-12-25 16:30:44 +01:00
68faa16e1d Tables: report auto-fit width in EndTable(), extracted TableGetColumnWidthAuto(). fix minor flickering with IsPreserveWidthAuto (which is a debug feature still), moved some code. 2020-12-25 15:52:42 +01:00
3573195112 Tables: (breaking) rename ImGuiTableFlags_ColumnsWidthStretch > ImGuiTableFlags_SizingPolicyStretch, ImGuiTableFlags_ColumnsWidthFixed > ImGuiTableFlags_SizingPolicyFixed in prevision for other policies. 2020-12-24 18:32:27 +01:00
b015ea93fd Style tweaks, disabled default window rounding by default, reduced size of resize grip, made less prominent, increased WindowBg alpha in classic style.
TestEngine: Fixed Checkbox() not reporting its checkable state when clipped.
2020-12-24 18:31:51 +01:00
3fbb928c9f Tables: explicit/custom width in TableSetupColumn() is reapplied when table or column becomes not resizable. Comments. 2020-12-23 12:14:55 +01:00
956435768f Tables: (breaking) renamed ImGuiTableColumnFlags_WidthAutoResize to _WidthAuto., default to WidthFixed policy when host window has auto-resize.
Fix edge case with TableSetColumnWidth on small windows (amend 972ca816)
2020-12-23 11:39:15 +01:00
d497f112e7 Tables: simplified and tidying up TableSetColumnWidth(), fixes resizing a fixed column surrounded by stretch column (manually or via auto-fit menu). TableHeader() showing highlighted when held. 2020-12-22 17:13:11 +01:00
972ca8166f Tables: extracted code for TableGetMaxColumnWidth(), fixing "stuck" resize being lossy as it used an older calculation for it and didn't honor e.g. _NoKeepColumnsVisible 2020-12-22 16:40:52 +01:00
1aa59f90d0 Minor API comments and tweaks, standardize index used in imgui.h. Tables: tweaked TableSetupColumn() assert to use IM_ASSERT_USER_ERROR(). 2020-12-22 15:30:26 +01:00
2e48c2da81 Removed redirecting functions/enums names that were marked obsolete in 1.63 (August 2018) + tables tweaks. 2020-12-21 19:42:37 +01:00
4d8e839ddf Renamed ImDrawList::AddBezierCurve() to ImDrawList::AddBezierCubic(), ImDrawList::PathBezierCurveTo() to ImDrawList::PathBezierCubicCurveTo(). (#3127, #3664, #3665)
Renamed corresponding internal functions as well.
2020-12-21 17:13:36 +01:00
550bfcfc59 Amend defce31 Add ImDrawList::AddQuadBezierCurve(), ImDrawList::PathQuadBezierCurveTo() (#3127, #3664, #3665) 2020-12-21 16:30:10 +01:00
defce31c2e Add ImDrawList::AddQuadBezierCurve(), ImDrawList::PathQuadBezierCurveTo() (#3127, #3664, #3665) 2020-12-21 16:25:14 +01:00
a640698123 Clipper: Fixed incorrect end-list positioning when using ImGuiListClipper with 1 item (bug in 1.79). (#3663) 2020-12-21 15:53:42 +01:00
ae63d56426 Tables: remove ImGuiTableFlags_NoHeadersWidth since it is so rarely used and can be specified on a per-column basis. 2020-12-18 19:03:47 +01:00
532aa5a69b Tables: (breaking) change outer_size.x default value to -FLT_MIN, make outer_size.x == 0.0f act as ImGuiTableFlags_NoHostExtendX (#3605, ad83976b) when no scrolling and no stretch column. Which is more consistent.
Demo: moved "Compact table" to "Padding" section, makes more sense. Tweaked demo.
2020-12-18 17:51:50 +01:00
22ace4438c Tables: clarify assumption that rendering of bg/borders in bg0/bg1 are cpu-clipped allowing frozen/unfrozen to share drawcmd + remove offset on outer borders of scrolling tables. 2020-12-18 14:33:16 +01:00
30468829c2 Tables: Internal: Maintain InnerRect to further clarify some code. Renamed Bg1 fields to Bg2 (used by Selectable) as the other handles Bg0+Bg1. 2020-12-18 14:32:51 +01:00
ad83976b35 Tables: Added ImGuiTableFlags_NoHostExtendX (#3605) marked as WIP, will probably rename.
Moved some code from BeginTable() to TableUpdateLayout() to late latch some of the required data.
2020-12-18 14:32:51 +01:00
c4dbab8f5e Tables: reset all width apply to hidden stretch columns. Comments. 2020-12-16 17:12:21 +01:00
1fb26d18c4 Tables: fixed seemingly unnecessarily copy of ImGuiTableColumnFlags_NoDirectResize_ which broken resizing from W3| in a F1 W3 F2 setup. Header only allow overlap on hover, not when active (amend f2df804f)
Otherwise TableUpdateBorders() tends to override mouse cursor.
2020-12-16 15:43:51 +01:00
892b48e2d6 Tables: Lock contents width while resizing down an horizontal scrolling table. Headers declare ideal width regardless of clipping. Misc comments. 2020-12-16 13:04:49 +01:00
bd899efbd0 Tables: fixed "resize to default" of multiple stretch column (added 3b3503e, broken 7a61f340).
Fixed a warning.
Storing RightMostStretchedColumn column for resizing code.
Avoid clearing RightMostEnabledColumn in BeginTable() so resizing code can potentially use it.
(Added regression tests for resize all to default imgui_dev)
2020-12-14 15:49:20 +01:00
f2df804fcc Tables: four small fixes.
Fixed last item flags leaking to disabled column, affecting IsItemHovered(). (#3651).
Validate and fix invalid DisplayOrder data from ini file.
Allow TableHeaderRows() to function will missing TableSetupColumn() calls.
Made TableHeader() use AllowItemOverlap mode to allow submit subsequent item in same cell, since it covers the whole cell area.
2020-12-13 19:57:19 +01:00
738606a294 Tables: added ImGuiTableFlags_SortTristate. Renamed ImGuiTableFlags_MultiSortable to ImGuiTableFlags_SortMulti. Removed now unused FlagsIn storage. 2020-12-11 23:01:09 +01:00
cad8935bfd Tables: revert setting colum cliprect.max.x to WorkMax.x instead of Max.x at it complicates header code. Fix clipped sort arrow. (amend 17536f9a) 2020-12-11 21:31:55 +01:00
bff1836922 Internals: added facility to hide windows from render without interfering with the HiddenFramesCanSkipItems/HiddenFramesCannotSkipItems fields which have effects on layout. Compact some fields.
Ideally we'd have a simpler system but it's not easy to make the capture system change to hook at the right spot. Will rework.
2020-12-11 14:37:58 +01:00
1ad5502f18 Tables: Closer to zero-clear constructor. Lazily clearing name offsets to avoid an iteration in BeginTable(). Removed unused TableSetColumnIsEnabled(), signature went faulty anyway. 2020-12-10 19:45:20 +01:00
76964a27ce Tables: moved TableNextRow(), TableBeginRow(), TableEndRow(), TableNextColumn(), TableBeginCell(), TableEndCell() to their own section. 2020-12-10 18:39:37 +01:00
e6b875c09b Tables: Ditch old columns flags/setting if not called again. Displaying right-most border when using _SameWidths. Moving Width-related functions to their own section.
Effectively removed the TableFixColumnFlags() in first loop of TableUpdateLayout() to replace it with similar one but only when column not declared. I think this should be the right thing.
2020-12-10 18:33:33 +01:00
3346544cf5 Examples: Fix batch files (amend b1a18d82, #3513), standardize them + DirectX12: Move ImGui::Render() call above the first barrier to clarify its lack of effect on the graphics pipe. 2020-12-09 18:28:02 +01:00
17536f9add Tables: more consistent use of CellPadding.x*2 and clip-rect on right-most side of non-bordered column + fix cellbg for standalone TableHeader call.
Using CellPadding.x on both sides when BorderV is off, generally most consistent and with default value (4,2) promotes at-glance visible spacing between non-bordered columns. Effectively double horizontal padding on non-bordered columns.
Made ClipRect.Max.x matches WorkMaxX which is where we'd like to go for windows themselves.
TableHeader() submit single cell bg color if not already submitted as a full header row.
Misc comments/docs updates.
2020-12-09 15:13:09 +01:00
64 changed files with 5253 additions and 2443 deletions

View File

@ -1,8 +1,8 @@
name: build
on:
push: {}
pull_request: {}
push:
pull_request:
schedule:
- cron: '0 9 * * *'
@ -12,21 +12,19 @@ jobs:
env:
VS_PATH: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\
MSBUILD_PATH: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\
# Until gh-actions allow us to use env variables inside other env variables (because we need %GITHUB_WORKSPACE%) we have to use relative path to imgui/examples/example_name directory.
SDL2_DIR: ..\..\SDL2-devel-2.0.10-VC\SDL2-2.0.10\
VULKAN_SDK: ..\..\vulkan-sdk-1.1.121.2\
steps:
- uses: actions/checkout@v1
with:
fetch-depth: 1
- uses: actions/checkout@v2
- name: Install Dependencies
shell: powershell
run: |
Invoke-WebRequest -Uri "https://www.libsdl.org/release/SDL2-devel-2.0.10-VC.zip" -OutFile "SDL2-devel-2.0.10-VC.zip"
Expand-Archive -Path SDL2-devel-2.0.10-VC.zip
echo "SDL2_DIR=$(pwd)\SDL2-devel-2.0.10-VC\SDL2-2.0.10\" >>${env:GITHUB_ENV}
Invoke-WebRequest -Uri "https://github.com/ocornut/imgui/files/3789205/vulkan-sdk-1.1.121.2.zip" -OutFile vulkan-sdk-1.1.121.2.zip
Expand-Archive -Path vulkan-sdk-1.1.121.2.zip
echo "VULKAN_SDK=$(pwd)\vulkan-sdk-1.1.121.2\" >>${env:GITHUB_ENV}
- name: Fix Projects
shell: powershell
@ -55,24 +53,33 @@ jobs:
- name: Build example_null (single file build)
shell: bash
run: |
echo '#define IMGUI_IMPLEMENTATION' > example_single_file.cpp
echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp
echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp
cat > example_single_file.cpp <<'EOF'
#define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
g++ -I. -Wall -Wformat -o example_single_file.exe example_single_file.cpp
- name: Build example_null (with IMGUI_DISABLE_WIN32_FUNCTIONS)
shell: bash
run: |
echo '#define IMGUI_DISABLE_WIN32_FUNCTIONS' > example_single_file.cpp
echo '#define IMGUI_IMPLEMENTATION' >> example_single_file.cpp
echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp
echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp
cat > example_single_file.cpp <<'EOF'
#define IMGUI_DISABLE_WIN32_FUNCTIONS
#define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
g++ -I. -Wall -Wformat -o example_single_file.exe example_single_file.cpp
- name: Build example_null (as DLL)
shell: cmd
run: |
call "%VS_PATH%\VC\Auxiliary\Build\vcvars64.bat"
echo #ifdef _EXPORT > example_single_file.cpp
echo # define IMGUI_API __declspec(dllexport) >> example_single_file.cpp
echo #else >> example_single_file.cpp
@ -80,6 +87,7 @@ jobs:
echo #endif >> example_single_file.cpp
echo #define IMGUI_IMPLEMENTATION >> example_single_file.cpp
echo #include "misc/single_file/imgui_single_file.h" >> example_single_file.cpp
cl.exe /D_USRDLL /D_WINDLL /D_EXPORT /I. example_single_file.cpp /LD /FeImGui.dll /link
cl.exe /I. ImGui.lib /Feexample_null.exe examples/example_null/main.cpp
@ -183,9 +191,7 @@ jobs:
Linux:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v1
with:
fetch-depth: 1
- uses: actions/checkout@v2
- name: Install Dependencies
run: |
@ -219,82 +225,118 @@ jobs:
- name: Build example_null (single file build)
run: |
echo '#define IMGUI_IMPLEMENTATION' > example_single_file.cpp
echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp
echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp
cat > example_single_file.cpp <<'EOF'
#define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with ImWchar32)
run: |
echo '#define IMGUI_USE_WCHAR32' > example_single_file.cpp
echo '#define IMGUI_IMPLEMENTATION' >> example_single_file.cpp
echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp
echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp
cat > example_single_file.cpp <<'EOF'
#define IMGUI_USE_WCHAR32
#define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with large ImDrawIdx)
run: |
echo '#define ImDrawIdx unsigned int' > example_single_file.cpp
echo '#define IMGUI_IMPLEMENTATION' >> example_single_file.cpp
echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp
echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp
cat > example_single_file.cpp <<'EOF'
#define ImDrawIdx unsigned int
#define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with IMGUI_DISABLE_OBSOLETE_FUNCTIONS)
run: |
echo '#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS' > example_single_file.cpp
echo '#define IMGUI_IMPLEMENTATION' >> example_single_file.cpp
echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp
echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp
cat > example_single_file.cpp <<'EOF'
#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
#define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with IMGUI_DISABLE_DEMO_WINDOWS and IMGUI_DISABLE_METRICS_WINDOW)
run: |
echo '#define IMGUI_DISABLE_DEMO_WINDOWS' > example_single_file.cpp
echo '#define IMGUI_DISABLE_METRICS_WINDOW' >> example_single_file.cpp
echo '#define IMGUI_IMPLEMENTATION' >> example_single_file.cpp
echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp
echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp
cat > example_single_file.cpp <<'EOF'
#define IMGUI_DISABLE_DEMO_WINDOWS
#define IMGUI_DISABLE_METRICS_WINDOW
#define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with IMGUI_DISABLE_FILE_FUNCTIONS)
run: |
echo '#define IMGUI_DISABLE_FILE_FUNCTIONS' > example_single_file.cpp
echo '#define IMGUI_IMPLEMENTATION' >> example_single_file.cpp
echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp
echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp
cat > example_single_file.cpp <<'EOF'
#define IMGUI_DISABLE_FILE_FUNCTIONS
#define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with IMGUI_USE_BGRA_PACKED_COLOR)
run: |
echo '#define IMGUI_USE_BGRA_PACKED_COLOR' > example_single_file.cpp
echo '#define IMGUI_IMPLEMENTATION' >> example_single_file.cpp
echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp
echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp
cat > example_single_file.cpp <<'EOF'
#define IMGUI_USE_BGRA_PACKED_COLOR
#define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with IM_VEC2_CLASS_EXTRA and IM_VEC4_CLASS_EXTRA)
run: |
echo 'struct MyVec2 { float x; float y; MyVec2(float x, float y) : x(x), y(y) { } };' > example_single_file.cpp
echo 'struct MyVec4 { float x; float y; float z; float w;' >> example_single_file.cpp
echo 'MyVec4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) { } };' >> example_single_file.cpp
echo '#define IM_VEC2_CLASS_EXTRA \' >> example_single_file.cpp
echo ' ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \' >> example_single_file.cpp
echo ' operator MyVec2() const { return MyVec2(x, y); }' >> example_single_file.cpp
echo '#define IM_VEC4_CLASS_EXTRA \' >> example_single_file.cpp
echo ' ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \' >> example_single_file.cpp
echo ' operator MyVec4() const { return MyVec4(x, y, z, w); }' >> example_single_file.cpp
echo '#define IMGUI_IMPLEMENTATION' >> example_single_file.cpp
echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp
echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp
cat > example_single_file.cpp <<'EOF'
struct MyVec2 { float x; float y; MyVec2(float x, float y) : x(x), y(y) { } };
struct MyVec4 { float x; float y; float z; float w;
MyVec4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) { } };
#define IM_VEC2_CLASS_EXTRA \
ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \
operator MyVec2() const { return MyVec2(x, y); }
#define IM_VEC4_CLASS_EXTRA \
ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \
operator MyVec4() const { return MyVec4(x, y, z, w); }
#define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (without c++ runtime, Clang)
run: |
echo '#define IMGUI_IMPLEMENTATION' > example_single_file.cpp
echo '#define IMGUI_DISABLE_DEMO_WINDOWS' >> example_single_file.cpp
echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp
echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp
cat > example_single_file.cpp <<'EOF'
#define IMGUI_IMPLEMENTATION
#define IMGUI_DISABLE_DEMO_WINDOWS
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
clang++ -I. -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp
- name: Build example_glfw_opengl2
@ -314,30 +356,35 @@ jobs:
MacOS:
runs-on: macOS-latest
steps:
- uses: actions/checkout@v1
with:
fetch-depth: 1
- uses: actions/checkout@v2
- name: Install Dependencies
run: |
brew install glfw3
brew install sdl2
brew install glfw3 sdl2
- name: Build example_null (extra warnings, clang 64-bit)
run: make -C examples/example_null WITH_EXTRA_WARNINGS=1
- name: Build example_null (single file build)
run: |
echo '#define IMGUI_IMPLEMENTATION' > example_single_file.cpp
echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp
echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp
cat > example_single_file.cpp <<'EOF'
#define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
clang++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (without c++ runtime)
run: |
echo '#define IMGUI_IMPLEMENTATION' > example_single_file.cpp
echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp
echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp
cat > example_single_file.cpp <<'EOF'
#define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h"
#include "examples/example_null/main.cpp"
EOF
clang++ -I. -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp
- name: Build example_glfw_opengl2
@ -369,9 +416,7 @@ jobs:
iOS:
runs-on: macOS-latest
steps:
- uses: actions/checkout@v1
with:
fetch-depth: 1
- uses: actions/checkout@v2
- name: Build example_apple_metal
run: |
@ -381,9 +426,7 @@ jobs:
Emscripten:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v1
with:
fetch-depth: 1
- uses: actions/checkout@v2
- name: Install Dependencies
run: |
@ -400,6 +443,13 @@ jobs:
popd
make -C examples/example_emscripten_opengl3
- name: Build example_emscripten_wgpu
run: |
pushd emsdk-master
source ./emsdk_env.sh
popd
make -C examples/example_emscripten_wgpu
Discord-CI:
runs-on: ubuntu-18.04
if: always()

3
.gitignore vendored
View File

@ -34,7 +34,8 @@ xcuserdata
examples/*.o.tmp
examples/*.out.js
examples/*.out.wasm
examples/example_emscripten_opengl3/example_emscripten_opengl3.*
examples/example_emscripten_opengl3/web/*
examples/example_emscripten_wgpu/web/*
## JetBrains IDE artifacts
.idea

View File

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2014-2020 Omar Cornut
Copyright (c) 2014-2021 Omar Cornut
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -206,7 +206,7 @@ bool ImGui_ImplAllegro5_CreateDeviceObjects()
return false;
// Store our identifier
io.Fonts->TexID = (void*)cloned_img;
io.Fonts->SetTexID((void*)cloned_img);
g_Texture = cloned_img;
// Create an invisible mouse cursor
@ -222,8 +222,9 @@ void ImGui_ImplAllegro5_InvalidateDeviceObjects()
{
if (g_Texture)
{
ImGuiIO& io = ImGui::GetIO();
io.Fonts->SetTexID(NULL);
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
g_Texture = NULL;
}
if (g_MouseCursorInvisible)

View File

@ -305,7 +305,7 @@ static void ImGui_ImplDX10_CreateFontsTexture()
}
// Store our identifier
io.Fonts->TexID = (ImTextureID)g_pFontTextureView;
io.Fonts->SetTexID((ImTextureID)g_pFontTextureView);
// Create texture sampler
{
@ -482,7 +482,7 @@ void ImGui_ImplDX10_InvalidateDeviceObjects()
return;
if (g_pFontSampler) { g_pFontSampler->Release(); g_pFontSampler = NULL; }
if (g_pFontTextureView) { g_pFontTextureView->Release(); g_pFontTextureView = NULL; ImGui::GetIO().Fonts->TexID = NULL; } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
if (g_pFontTextureView) { g_pFontTextureView->Release(); g_pFontTextureView = NULL; ImGui::GetIO().Fonts->SetTexID(NULL); } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
if (g_pIB) { g_pIB->Release(); g_pIB = NULL; }
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }

View File

@ -317,7 +317,7 @@ static void ImGui_ImplDX11_CreateFontsTexture()
}
// Store our identifier
io.Fonts->TexID = (ImTextureID)g_pFontTextureView;
io.Fonts->SetTexID((ImTextureID)g_pFontTextureView);
// Create texture sampler
{
@ -494,7 +494,7 @@ void ImGui_ImplDX11_InvalidateDeviceObjects()
return;
if (g_pFontSampler) { g_pFontSampler->Release(); g_pFontSampler = NULL; }
if (g_pFontTextureView) { g_pFontTextureView->Release(); g_pFontTextureView = NULL; ImGui::GetIO().Fonts->TexID = NULL; } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
if (g_pFontTextureView) { g_pFontTextureView->Release(); g_pFontTextureView = NULL; ImGui::GetIO().Fonts->SetTexID(NULL); } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
if (g_pIB) { g_pIB->Release(); g_pIB = NULL; }
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }

View File

@ -7,7 +7,7 @@
// Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'.
// This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*.
// This define is done in the example .vcxproj file and need to be replicated in your app (by e.g. editing imconfig.h)
// This define is set in the example .vcxproj file and need to be replicated in your app or by adding it to your imconfig.h file.
// You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
@ -15,6 +15,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2021-01-11: DirectX12: Improve Windows 7 compatibility (for D3D12On7) by loading d3d12.dll dynamically.
// 2020-09-16: DirectX12: Avoid rendering calls with zero-sized scissor rectangle since it generates a validation layer warning.
// 2020-09-08: DirectX12: Clarified support for building on 32-bit systems by redefining ImTextureID.
// 2019-10-18: DirectX12: *BREAKING CHANGE* Added extra ID3D12DescriptorHeap parameter to ImGui_ImplDX12_Init() function.
@ -394,7 +395,7 @@ static void ImGui_ImplDX12_CreateFontsTexture()
// Store our identifier
static_assert(sizeof(ImTextureID) >= sizeof(g_hFontSrvGpuDescHandle.ptr), "Can't pack descriptor handle into TexID, 32-bit not supported yet.");
io.Fonts->TexID = (ImTextureID)g_hFontSrvGpuDescHandle.ptr;
io.Fonts->SetTexID((ImTextureID)g_hFontSrvGpuDescHandle.ptr);
}
bool ImGui_ImplDX12_CreateDeviceObjects()
@ -452,8 +453,34 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS |
D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS;
// Load d3d12.dll and D3D12SerializeRootSignature() function address dynamically to facilitate using with D3D12On7.
// See if any version of d3d12.dll is already loaded in the process. If so, give preference to that.
static HINSTANCE d3d12_dll = ::GetModuleHandleA("d3d12.dll");
if (d3d12_dll == NULL)
{
// Attempt to load d3d12.dll from local directories. This will only succeed if
// (1) the current OS is Windows 7, and
// (2) there exists a version of d3d12.dll for Windows 7 (D3D12On7) in one of the following directories.
// See https://github.com/ocornut/imgui/pull/3696 for details.
const char* localD3d12Paths[] = { ".\\d3d12.dll", ".\\d3d12on7\\d3d12.dll", ".\\12on7\\d3d12.dll" }; // A. current directory, B. used by some games, C. used in Microsoft D3D12On7 sample
for (int i = 0; i < IM_ARRAYSIZE(localD3d12Paths); i++)
if ((d3d12_dll = ::LoadLibraryA(localD3d12Paths[i])) != NULL)
break;
// If failed, we are on Windows >= 10.
if (d3d12_dll == NULL)
d3d12_dll = ::LoadLibraryA("d3d12.dll");
if (d3d12_dll == NULL)
return false;
}
PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignatureFn = (PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)::GetProcAddress(d3d12_dll, "D3D12SerializeRootSignature");
if (D3D12SerializeRootSignatureFn == NULL)
return false;
ID3DBlob* blob = NULL;
if (D3D12SerializeRootSignature(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &blob, NULL) != S_OK)
if (D3D12SerializeRootSignatureFn(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &blob, NULL) != S_OK)
return false;
g_pd3dDevice->CreateRootSignature(0, blob->GetBufferPointer(), blob->GetBufferSize(), IID_PPV_ARGS(&g_pRootSignature));
@ -613,7 +640,7 @@ void ImGui_ImplDX12_InvalidateDeviceObjects()
SafeRelease(g_pFontTextureResource);
ImGuiIO& io = ImGui::GetIO();
io.Fonts->TexID = NULL; // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
io.Fonts->SetTexID(NULL); // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
for (UINT i = 0; i < g_numFramesInFlight; i++)
{

View File

@ -7,7 +7,7 @@
// Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'.
// This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*.
// This define is done in the example .vcxproj file and need to be replicated in your app (by e.g. editing imconfig.h)
// This define is set in the example .vcxproj file and need to be replicated in your app or by adding it to your imconfig.h file.
// You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
@ -16,6 +16,11 @@
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable: 4471) // a forward declaration of an unscoped enumeration must have an underlying type
#endif
enum DXGI_FORMAT;
struct ID3D12Device;
struct ID3D12DescriptorHeap;
@ -36,3 +41,8 @@ IMGUI_IMPL_API void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3
// Use if you want to reset your rendering device without losing Dear ImGui state.
IMGUI_IMPL_API void ImGui_ImplDX12_InvalidateDeviceObjects();
IMGUI_IMPL_API bool ImGui_ImplDX12_CreateDeviceObjects();
#ifdef _MSC_VER
#pragma warning (pop)
#endif

View File

@ -253,7 +253,7 @@ static bool ImGui_ImplDX9_CreateFontsTexture()
g_FontTexture->UnlockRect(0);
// Store our identifier
io.Fonts->TexID = (ImTextureID)g_FontTexture;
io.Fonts->SetTexID((ImTextureID)g_FontTexture);
return true;
}
@ -273,7 +273,7 @@ void ImGui_ImplDX9_InvalidateDeviceObjects()
return;
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pIB) { g_pIB->Release(); g_pIB = NULL; }
if (g_FontTexture) { g_FontTexture->Release(); g_FontTexture = NULL; ImGui::GetIO().Fonts->TexID = NULL; } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
if (g_FontTexture) { g_FontTexture->Release(); g_FontTexture = NULL; ImGui::GetIO().Fonts->SetTexID(NULL); } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
}
void ImGui_ImplDX9_NewFrame()

View File

@ -1,5 +1,5 @@
// dear imgui: Platform Backend for GLFW
// This needs to be used along with a Renderer (e.g. OpenGL3, Vulkan..)
// This needs to be used along with a Renderer (e.g. OpenGL3, Vulkan, WebGPU..)
// (Info: GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.)
// (Requires: GLFW 3.1+)
@ -231,6 +231,11 @@ bool ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool install_callbacks)
return ImGui_ImplGlfw_Init(window, install_callbacks, GlfwClientApi_Vulkan);
}
bool ImGui_ImplGlfw_InitForOther(GLFWwindow* window, bool install_callbacks)
{
return ImGui_ImplGlfw_Init(window, install_callbacks, GlfwClientApi_Unknown);
}
void ImGui_ImplGlfw_Shutdown()
{
if (g_InstalledCallbacks)

View File

@ -1,5 +1,5 @@
// dear imgui: Platform Backend for GLFW
// This needs to be used along with a Renderer (e.g. OpenGL3, Vulkan..)
// This needs to be used along with a Renderer (e.g. OpenGL3, Vulkan, WebGPU..)
// (Info: GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.)
// Implemented features:
@ -23,6 +23,7 @@ struct GLFWwindow;
IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForOpenGL(GLFWwindow* window, bool install_callbacks);
IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool install_callbacks);
IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForOther(GLFWwindow* window, bool install_callbacks);
IMGUI_IMPL_API void ImGui_ImplGlfw_Shutdown();
IMGUI_IMPL_API void ImGui_ImplGlfw_NewFrame();

View File

@ -1,8 +1,8 @@
// dear imgui: Platform Backend for GLUT/FreeGLUT
// This needs to be used along with a Renderer (e.g. OpenGL2)
// !!! GLUT/FreeGLUT IS OBSOLETE SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!!
// !!! If someone or something is teaching you GLUT in 2020, you are being abused. Please show some resistance. !!!
// !!! GLUT/FreeGLUT IS OBSOLETE PREHISTORIC SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!!
// !!! If someone or something is teaching you GLUT today, you are being abused. Please show some resistance. !!!
// !!! Nowadays, prefer using GLFW or SDL instead!
// Issues:

View File

@ -1,8 +1,8 @@
// dear imgui: Platform Backend for GLUT/FreeGLUT
// This needs to be used along with a Renderer (e.g. OpenGL2)
// !!! GLUT/FreeGLUT IS OBSOLETE SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!!
// !!! If someone or something is teaching you GLUT in 2020, you are being abused. Please show some resistance. !!!
// !!! GLUT/FreeGLUT IS OBSOLETE PREHISTORIC SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!!
// !!! If someone or something is teaching you GLUT today, you are being abused. Please show some resistance. !!!
// !!! Nowadays, prefer using GLFW or SDL instead!
// Issues:

View File

@ -194,7 +194,7 @@ bool ImGui_Marmalade_CreateDeviceObjects()
g_FontTexture->Upload();
// Store our identifier
io.Fonts->TexID = (ImTextureID)g_FontTexture;
io.Fonts->SetTexID((ImTextureID)g_FontTexture);
return true;
}
@ -209,8 +209,8 @@ void ImGui_Marmalade_InvalidateDeviceObjects()
if (g_FontTexture)
{
ImGui::GetIO().Fonts->SetTexID(0);
delete g_FontTexture;
ImGui::GetIO().Fonts->TexID = 0;
g_FontTexture = NULL;
}
}

View File

@ -11,6 +11,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2021-01-25: Metal: Fixed texture storage mode when building on Mac Catalyst.
// 2019-05-29: Metal: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
// 2019-04-30: Metal: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
// 2019-02-11: Metal: Projecting clipping rectangles correctly using draw_data->FramebufferScale to allow multi-viewports for retina display.
@ -113,7 +114,7 @@ bool ImGui_ImplMetal_CreateFontsTexture(id<MTLDevice> device)
[g_sharedMetalContext makeFontTextureWithDevice:device];
ImGuiIO& io = ImGui::GetIO();
io.Fonts->TexID = (__bridge void *)g_sharedMetalContext.fontTexture; // ImTextureID == void*
io.Fonts->SetTexID((__bridge void *)g_sharedMetalContext.fontTexture); // ImTextureID == void*
return (g_sharedMetalContext.fontTexture != nil);
}
@ -122,7 +123,7 @@ void ImGui_ImplMetal_DestroyFontsTexture()
{
ImGuiIO& io = ImGui::GetIO();
g_sharedMetalContext.fontTexture = nil;
io.Fonts->TexID = nullptr;
io.Fonts->SetTexID(nullptr);
}
bool ImGui_ImplMetal_CreateDeviceObjects(id<MTLDevice> device)
@ -238,7 +239,7 @@ void ImGui_ImplMetal_DestroyDeviceObjects()
height:(NSUInteger)height
mipmapped:NO];
textureDescriptor.usage = MTLTextureUsageShaderRead;
#if TARGET_OS_OSX
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
textureDescriptor.storageMode = MTLStorageModeManaged;
#else
textureDescriptor.storageMode = MTLStorageModeShared;

View File

@ -18,7 +18,8 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2020-01-23: OpenGL: Explicitly backup, setup and restore GL_TEXTURE_ENV to increase compatibility with legacy OpenGL applications.
// 2021-01-03: OpenGL: Backup, setup and restore GL_SHADE_MODEL state, disable GL_STENCIL_TEST and disable GL_NORMAL_ARRAY client state to increase compatibility with legacy OpenGL applications.
// 2020-01-23: OpenGL: Backup, setup and restore GL_TEXTURE_ENV to increase compatibility with legacy OpenGL applications.
// 2019-04-30: OpenGL: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
// 2019-02-11: OpenGL: Projecting clipping rectangles correctly using draw_data->FramebufferScale to allow multi-viewports for retina display.
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
@ -82,23 +83,29 @@ static void ImGui_ImplOpenGL2_SetupRenderState(ImDrawData* draw_data, int fb_wid
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glDisable(GL_STENCIL_TEST);
glDisable(GL_LIGHTING);
glDisable(GL_COLOR_MATERIAL);
glEnable(GL_SCISSOR_TEST);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glEnable(GL_TEXTURE_2D);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glShadeModel(GL_SMOOTH);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
// If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!),
// you may need to backup/reset/restore current shader using the lines below. DO NOT MODIFY THIS FILE! Add the code in your calling function:
// GLint last_program;
// glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
// glUseProgram(0);
// ImGui_ImplOpenGL2_RenderDrawData(...);
// glUseProgram(last_program)
// you may need to backup/reset/restore other state, e.g. for current shader using the commented lines below.
// (DO NOT MODIFY THIS FILE! Add the code in your calling function)
// GLint last_program;
// glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
// glUseProgram(0);
// ImGui_ImplOpenGL2_RenderDrawData(...);
// glUseProgram(last_program)
// There are potentially many more states you could need to clear/setup that we can't access from default headers.
// e.g. glBindBuffer(GL_ARRAY_BUFFER, 0), glDisable(GL_TEXTURE_CUBE_MAP).
// Setup viewport, orthographic projection matrix
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
@ -128,6 +135,7 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
GLint last_shade_model; glGetIntegerv(GL_SHADE_MODEL, &last_shade_model);
GLint last_tex_env_mode; glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &last_tex_env_mode);
glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT);
@ -196,6 +204,7 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]); glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]);
glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]);
glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]);
glShadeModel(last_shade_model);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, last_tex_env_mode);
}
@ -218,7 +227,7 @@ bool ImGui_ImplOpenGL2_CreateFontsTexture()
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
// Store our identifier
io.Fonts->TexID = (ImTextureID)(intptr_t)g_FontTexture;
io.Fonts->SetTexID((ImTextureID)(intptr_t)g_FontTexture);
// Restore state
glBindTexture(GL_TEXTURE_2D, last_texture);
@ -232,7 +241,7 @@ void ImGui_ImplOpenGL2_DestroyFontsTexture()
{
ImGuiIO& io = ImGui::GetIO();
glDeleteTextures(1, &g_FontTexture);
io.Fonts->TexID = 0;
io.Fonts->SetTexID(0);
g_FontTexture = 0;
}
}

View File

@ -13,7 +13,8 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2020-10-23: OpenGL: Save and restore current GL_PRIMITIVE_RESTART state.
// 2021-01-03: OpenGL: Backup, setup and restore GL_STENCIL_TEST state.
// 2020-10-23: OpenGL: Backup, setup and restore GL_PRIMITIVE_RESTART state.
// 2020-10-15: OpenGL: Use glGetString(GL_VERSION) instead of glGetIntegerv(GL_MAJOR_VERSION, ...) when the later returns zero (e.g. Desktop GL 2.x)
// 2020-09-17: OpenGL: Fix to avoid compiling/calling glBindSampler() on ES or pre 3.3 context which have the defines set by a loader.
// 2020-07-10: OpenGL: Added support for glad2 OpenGL loader.
@ -249,6 +250,7 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glDisable(GL_STENCIL_TEST);
glEnable(GL_SCISSOR_TEST);
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
if (g_GlVersion >= 310)
@ -259,8 +261,8 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
#endif
// Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT)
bool clip_origin_lower_left = true;
#if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__)
bool clip_origin_lower_left = true;
GLenum current_clip_origin = 0; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)&current_clip_origin);
if (current_clip_origin == GL_UPPER_LEFT)
clip_origin_lower_left = false;
@ -273,7 +275,9 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
float T = draw_data->DisplayPos.y;
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
#if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__)
if (!clip_origin_lower_left) { float tmp = T; T = B; B = tmp; } // Swap top and bottom if origin is upper left
#endif
const float ortho_projection[4][4] =
{
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
@ -284,12 +288,12 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
glUseProgram(g_ShaderHandle);
glUniform1i(g_AttribLocationTex, 0);
glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
if (g_GlVersion >= 330)
glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise.
#endif
(void)vertex_array_object;
#ifndef IMGUI_IMPL_OPENGL_ES2
glBindVertexArray(vertex_array_object);
@ -343,6 +347,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
GLboolean last_enable_blend = glIsEnabled(GL_BLEND);
GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE);
GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST);
GLboolean last_enable_stencil_test = glIsEnabled(GL_STENCIL_TEST);
GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
GLboolean last_enable_primitive_restart = (g_GlVersion >= 310) ? glIsEnabled(GL_PRIMITIVE_RESTART) : GL_FALSE;
@ -431,6 +436,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND);
if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE);
if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
if (last_enable_stencil_test) glEnable(GL_STENCIL_TEST); else glDisable(GL_STENCIL_TEST);
if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST);
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
if (g_GlVersion >= 310) { if (last_enable_primitive_restart) glEnable(GL_PRIMITIVE_RESTART); else glDisable(GL_PRIMITIVE_RESTART); }
@ -464,7 +470,7 @@ bool ImGui_ImplOpenGL3_CreateFontsTexture()
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
// Store our identifier
io.Fonts->TexID = (ImTextureID)(intptr_t)g_FontTexture;
io.Fonts->SetTexID((ImTextureID)(intptr_t)g_FontTexture);
// Restore state
glBindTexture(GL_TEXTURE_2D, last_texture);
@ -478,7 +484,7 @@ void ImGui_ImplOpenGL3_DestroyFontsTexture()
{
ImGuiIO& io = ImGui::GetIO();
glDeleteTextures(1, &g_FontTexture);
io.Fonts->TexID = 0;
io.Fonts->SetTexID(0);
g_FontTexture = 0;
}
}

View File

@ -18,6 +18,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2021-01-27: Inputs: Added a fix for mouse position not being reported when mouse buttons other than left one are down.
// 2020-10-28: Inputs: Added a fix for handling keypad-enter key.
// 2020-05-25: Inputs: Added a fix for missing trackpad clicks when done with "soft tap".
// 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor.
@ -226,7 +227,7 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
return io.WantCaptureMouse;
}
if (event.type == NSEventTypeMouseMoved || event.type == NSEventTypeLeftMouseDragged)
if (event.type == NSEventTypeMouseMoved || event.type == NSEventTypeLeftMouseDragged || event.type == NSEventTypeRightMouseDragged || event.type == NSEventTypeOtherMouseDragged)
{
NSPoint mousePoint = event.locationInWindow;
mousePoint = [view convertPoint:mousePoint fromView:nil];

View File

@ -22,6 +22,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2021-01-27: Vulkan: Added support for custom function load and IMGUI_IMPL_VULKAN_NO_PROTOTYPES by using ImGui_ImplVulkan_LoadFunctions().
// 2020-11-11: Vulkan: Added support for specifying which subpass to reference during VkPipeline creation.
// 2020-09-07: Vulkan: Added VkPipeline parameter to ImGui_ImplVulkan_RenderDrawData (default to one passed to ImGui_ImplVulkan_Init).
// 2020-05-04: Vulkan: Fixed crash if initial frame has no vertices.
@ -48,7 +49,6 @@
// 2016-10-18: Vulkan: Add location decorators & change to use structs as in/out in glsl, update embedded spv (produced with glslangValidator -x). Null the released resources.
// 2016-08-27: Vulkan: Fix Vulkan example for use when a depth buffer is active.
#include "imgui.h"
#include "imgui_impl_vulkan.h"
#include <stdio.h>
@ -85,6 +85,11 @@ static VkPipeline g_Pipeline = VK_NULL_HANDLE;
static uint32_t g_Subpass = 0;
static VkShaderModule g_ShaderModuleVert;
static VkShaderModule g_ShaderModuleFrag;
#ifdef VK_NO_PROTOTYPES
static bool g_FunctionsLoaded = false;
#else
static bool g_FunctionsLoaded = true;
#endif
// Font data
static VkSampler g_FontSampler = VK_NULL_HANDLE;
@ -107,6 +112,75 @@ void ImGui_ImplVulkanH_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVul
void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count);
void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator);
// Vulkan prototypes for use with custom loaders
// (see description of IMGUI_IMPL_VULKAN_NO_PROTOTYPES in imgui_impl_vulkan.h
#ifdef VK_NO_PROTOTYPES
#define IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_MAP_MACRO) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkAllocateCommandBuffers) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkAllocateDescriptorSets) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkAllocateMemory) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkBindBufferMemory) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkBindImageMemory) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdBindDescriptorSets) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdBindIndexBuffer) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdBindPipeline) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdBindVertexBuffers) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdCopyBufferToImage) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdDrawIndexed) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdPipelineBarrier) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdPushConstants) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdSetScissor) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdSetViewport) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateBuffer) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateCommandPool) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateDescriptorSetLayout) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateFence) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateFramebuffer) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateGraphicsPipelines) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateImage) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateImageView) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreatePipelineLayout) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateRenderPass) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateSampler) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateSemaphore) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateShaderModule) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateSwapchainKHR) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyBuffer) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyCommandPool) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyDescriptorSetLayout) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyFence) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyFramebuffer) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyImage) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyImageView) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyPipeline) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyPipelineLayout) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyRenderPass) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroySampler) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroySemaphore) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyShaderModule) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroySurfaceKHR) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroySwapchainKHR) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDeviceWaitIdle) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkFlushMappedMemoryRanges) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkFreeCommandBuffers) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkFreeMemory) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetBufferMemoryRequirements) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetImageMemoryRequirements) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceMemoryProperties) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceSurfaceCapabilitiesKHR) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceSurfaceFormatsKHR) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceSurfacePresentModesKHR) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetSwapchainImagesKHR) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkMapMemory) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkUnmapMemory) \
IMGUI_VULKAN_FUNC_MAP_MACRO(vkUpdateDescriptorSets)
// Define function pointers
#define IMGUI_VULKAN_FUNC_DEF(func) static PFN_##func func;
IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_DEF)
#undef IMGUI_VULKAN_FUNC_DEF
#endif // VK_NO_PROTOTYPES
//-----------------------------------------------------------------------------
// SHADERS
//-----------------------------------------------------------------------------
@ -587,7 +661,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer)
}
// Store our identifier
io.Fonts->TexID = (ImTextureID)(intptr_t)g_FontImage;
io.Fonts->SetTexID((ImTextureID)(intptr_t)g_FontImage);
return true;
}
@ -886,8 +960,31 @@ void ImGui_ImplVulkan_DestroyDeviceObjects()
if (g_Pipeline) { vkDestroyPipeline(v->Device, g_Pipeline, v->Allocator); g_Pipeline = VK_NULL_HANDLE; }
}
bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data)
{
// Load function pointers
// You can use the default Vulkan loader using:
// ImGui_ImplVulkan_LoadFunctions([](const char* function_name, void*) { return vkGetInstanceProcAddr(your_vk_isntance, function_name); });
// But this would be equivalent to not setting VK_NO_PROTOTYPES.
#ifdef VK_NO_PROTOTYPES
#define IMGUI_VULKAN_FUNC_LOAD(func) \
func = reinterpret_cast<decltype(func)>(loader_func(#func, user_data)); \
if (func == NULL) \
return false;
IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_LOAD)
#undef IMGUI_VULKAN_FUNC_LOAD
#else
IM_UNUSED(loader_func);
IM_UNUSED(user_data);
#endif
g_FunctionsLoaded = true;
return true;
}
bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass render_pass)
{
IM_ASSERT(g_FunctionsLoaded && "Need to call ImGui_ImplVulkan_LoadFunctions() if IMGUI_IMPL_VULKAN_NO_PROTOTYPES or VK_NO_PROTOTYPES are set!");
// Setup backend capabilities flags
ImGuiIO& io = ImGui::GetIO();
io.BackendRendererName = "imgui_impl_vulkan";
@ -952,6 +1049,7 @@ void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count)
VkSurfaceFormatKHR ImGui_ImplVulkanH_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space)
{
IM_ASSERT(g_FunctionsLoaded && "Need to call ImGui_ImplVulkan_LoadFunctions() if IMGUI_IMPL_VULKAN_NO_PROTOTYPES or VK_NO_PROTOTYPES are set!");
IM_ASSERT(request_formats != NULL);
IM_ASSERT(request_formats_count > 0);
@ -996,6 +1094,7 @@ VkSurfaceFormatKHR ImGui_ImplVulkanH_SelectSurfaceFormat(VkPhysicalDevice physic
VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkPresentModeKHR* request_modes, int request_modes_count)
{
IM_ASSERT(g_FunctionsLoaded && "Need to call ImGui_ImplVulkan_LoadFunctions() if IMGUI_IMPL_VULKAN_NO_PROTOTYPES or VK_NO_PROTOTYPES are set!");
IM_ASSERT(request_modes != NULL);
IM_ASSERT(request_modes_count > 0);
@ -1246,6 +1345,7 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
// Create or resize window
void ImGui_ImplVulkanH_CreateOrResizeWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int width, int height, uint32_t min_image_count)
{
IM_ASSERT(g_FunctionsLoaded && "Need to call ImGui_ImplVulkan_LoadFunctions() if IMGUI_IMPL_VULKAN_NO_PROTOTYPES or VK_NO_PROTOTYPES are set!");
(void)instance;
ImGui_ImplVulkanH_CreateWindowSwapChain(physical_device, device, wd, allocator, width, height, min_image_count);
ImGui_ImplVulkanH_CreateWindowCommandBuffers(physical_device, device, wd, queue_family, allocator);

View File

@ -22,25 +22,42 @@
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
// [Configuration] in order to use a custom Vulkan function loader:
// (1) You'll need to disable default Vulkan function prototypes.
// We provide a '#define IMGUI_IMPL_VULKAN_NO_PROTOTYPES' convenience configuration flag.
// In order to make sure this is visible from the imgui_impl_vulkan.cpp compilation unit:
// - Add '#define IMGUI_IMPL_VULKAN_NO_PROTOTYPES' in your imconfig.h file
// - Or as a compilation flag in your build system
// - Or uncomment here (not recommended because you'd be modifying imgui sources!)
// - Do not simply add it in a .cpp file!
// (2) Call ImGui_ImplVulkan_LoadFunctions() before ImGui_ImplVulkan_Init() with your custom function.
// If you have no idea what this is, leave it alone!
//#define IMGUI_IMPL_VULKAN_NO_PROTOTYPES
// Vulkan includes
#if defined(IMGUI_IMPL_VULKAN_NO_PROTOTYPES) && !defined(VK_NO_PROTOTYPES)
#define VK_NO_PROTOTYPES
#endif
#include <vulkan/vulkan.h>
// Initialization data, for ImGui_ImplVulkan_Init()
// [Please zero-clear before use!]
struct ImGui_ImplVulkan_InitInfo
{
VkInstance Instance;
VkPhysicalDevice PhysicalDevice;
VkDevice Device;
uint32_t QueueFamily;
VkQueue Queue;
VkPipelineCache PipelineCache;
VkDescriptorPool DescriptorPool;
uint32_t Subpass;
uint32_t MinImageCount; // >= 2
uint32_t ImageCount; // >= MinImageCount
VkSampleCountFlagBits MSAASamples; // >= VK_SAMPLE_COUNT_1_BIT
const VkAllocationCallbacks* Allocator;
void (*CheckVkResultFn)(VkResult err);
VkInstance Instance;
VkPhysicalDevice PhysicalDevice;
VkDevice Device;
uint32_t QueueFamily;
VkQueue Queue;
VkPipelineCache PipelineCache;
VkDescriptorPool DescriptorPool;
uint32_t Subpass;
uint32_t MinImageCount; // >= 2
uint32_t ImageCount; // >= MinImageCount
VkSampleCountFlagBits MSAASamples; // >= VK_SAMPLE_COUNT_1_BIT
const VkAllocationCallbacks* Allocator;
void (*CheckVkResultFn)(VkResult err);
};
// Called by user code
@ -52,6 +69,9 @@ IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer comm
IMGUI_IMPL_API void ImGui_ImplVulkan_DestroyFontUploadObjects();
IMGUI_IMPL_API void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count); // To override MinImageCount after initialization (e.g. if swap chain is recreated)
// Optional: load Vulkan functions with a custom function loader
// This is only useful with IMGUI_IMPL_VULKAN_NO_PROTOTYPES / VK_NO_PROTOTYPES
IMGUI_IMPL_API bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data = NULL);
//-------------------------------------------------------------------------
// Internal / Miscellaneous Vulkan Helpers

View File

@ -0,0 +1,782 @@
// dear imgui: Renderer for WebGPU
// This needs to be used along with a Platform Binding (e.g. GLFW)
// (Please note that WebGPU is currently experimental, will not run on non-beta browsers, and may break.)
// Implemented features:
// [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID!
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
// You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Read online: https://github.com/ocornut/imgui/tree/master/docs
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2021-01-28: Initial version.
#include "imgui.h"
#include "imgui_impl_wgpu.h"
#include <limits.h>
#include <webgpu/webgpu.h>
#define HAS_EMSCRIPTEN_VERSION(major, minor, tiny) (__EMSCRIPTEN_major__ > (major) || (__EMSCRIPTEN_major__ == (major) && __EMSCRIPTEN_minor__ > (minor)) || (__EMSCRIPTEN_major__ == (major) && __EMSCRIPTEN_minor__ == (minor) && __EMSCRIPTEN_tiny__ >= (tiny)))
// Dear ImGui prototypes from imgui_internal.h
extern ImGuiID ImHashData(const void* data_p, size_t data_size, ImU32 seed = 0);
// WebGPU data
static WGPUDevice g_wgpuDevice = NULL;
static WGPUTextureFormat g_renderTargetFormat = WGPUTextureFormat_Undefined;
static WGPURenderPipeline g_pipelineState = NULL;
struct RenderResources
{
WGPUTexture FontTexture; // Font texture
WGPUTextureView FontTextureView; // Texture view for font texture
WGPUSampler Sampler; // Sampler for the font texture
WGPUBuffer Uniforms; // Shader uniforms
WGPUBindGroup CommonBindGroup; // Resources bind-group to bind the common resources to pipeline
WGPUBindGroupLayout ImageBindGroupLayout; // Bind group layout for image textures
ImGuiStorage ImageBindGroups; // Resources bind-group to bind the font/image resources to pipeline (this is a key->value map)
WGPUBindGroup ImageBindGroup; // Default font-resource of Dear ImGui
};
static RenderResources g_resources;
struct FrameResources
{
WGPUBuffer IndexBuffer;
WGPUBuffer VertexBuffer;
ImDrawIdx* IndexBufferHost;
ImDrawVert* VertexBufferHost;
int IndexBufferSize;
int VertexBufferSize;
};
static FrameResources* g_pFrameResources = NULL;
static unsigned int g_numFramesInFlight = 0;
static unsigned int g_frameIndex = UINT_MAX;
struct Uniforms
{
float MVP[4][4];
};
//-----------------------------------------------------------------------------
// SHADERS
//-----------------------------------------------------------------------------
// glsl_shader.vert, compiled with:
// # glslangValidator -V -x -o glsl_shader.vert.u32 glsl_shader.vert
/*
#version 450 core
layout(location = 0) in vec2 aPos;
layout(location = 1) in vec2 aUV;
layout(location = 2) in vec4 aColor;
layout(set=0, binding = 0) uniform transform { mat4 mvp; };
out gl_PerVertex { vec4 gl_Position; };
layout(location = 0) out struct { vec4 Color; vec2 UV; } Out;
void main()
{
Out.Color = aColor;
Out.UV = aUV;
gl_Position = mvp * vec4(aPos, 0, 1);
}
*/
static uint32_t __glsl_shader_vert_spv[] =
{
0x07230203,0x00010000,0x00080007,0x0000002c,0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
0x000a000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000000b,0x0000000f,0x00000015,
0x0000001b,0x00000023,0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d,
0x00000000,0x00030005,0x00000009,0x00000000,0x00050006,0x00000009,0x00000000,0x6f6c6f43,
0x00000072,0x00040006,0x00000009,0x00000001,0x00005655,0x00030005,0x0000000b,0x0074754f,
0x00040005,0x0000000f,0x6c6f4361,0x0000726f,0x00030005,0x00000015,0x00565561,0x00060005,
0x00000019,0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006,0x00000019,0x00000000,
0x505f6c67,0x7469736f,0x006e6f69,0x00030005,0x0000001b,0x00000000,0x00050005,0x0000001d,
0x6e617274,0x726f6673,0x0000006d,0x00040006,0x0000001d,0x00000000,0x0070766d,0x00030005,
0x0000001f,0x00000000,0x00040005,0x00000023,0x736f5061,0x00000000,0x00040047,0x0000000b,
0x0000001e,0x00000000,0x00040047,0x0000000f,0x0000001e,0x00000002,0x00040047,0x00000015,
0x0000001e,0x00000001,0x00050048,0x00000019,0x00000000,0x0000000b,0x00000000,0x00030047,
0x00000019,0x00000002,0x00040048,0x0000001d,0x00000000,0x00000005,0x00050048,0x0000001d,
0x00000000,0x00000023,0x00000000,0x00050048,0x0000001d,0x00000000,0x00000007,0x00000010,
0x00030047,0x0000001d,0x00000002,0x00040047,0x0000001f,0x00000022,0x00000000,0x00040047,
0x0000001f,0x00000021,0x00000000,0x00040047,0x00000023,0x0000001e,0x00000000,0x00020013,
0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,
0x00000007,0x00000006,0x00000004,0x00040017,0x00000008,0x00000006,0x00000002,0x0004001e,
0x00000009,0x00000007,0x00000008,0x00040020,0x0000000a,0x00000003,0x00000009,0x0004003b,
0x0000000a,0x0000000b,0x00000003,0x00040015,0x0000000c,0x00000020,0x00000001,0x0004002b,
0x0000000c,0x0000000d,0x00000000,0x00040020,0x0000000e,0x00000001,0x00000007,0x0004003b,
0x0000000e,0x0000000f,0x00000001,0x00040020,0x00000011,0x00000003,0x00000007,0x0004002b,
0x0000000c,0x00000013,0x00000001,0x00040020,0x00000014,0x00000001,0x00000008,0x0004003b,
0x00000014,0x00000015,0x00000001,0x00040020,0x00000017,0x00000003,0x00000008,0x0003001e,
0x00000019,0x00000007,0x00040020,0x0000001a,0x00000003,0x00000019,0x0004003b,0x0000001a,
0x0000001b,0x00000003,0x00040018,0x0000001c,0x00000007,0x00000004,0x0003001e,0x0000001d,
0x0000001c,0x00040020,0x0000001e,0x00000002,0x0000001d,0x0004003b,0x0000001e,0x0000001f,
0x00000002,0x00040020,0x00000020,0x00000002,0x0000001c,0x0004003b,0x00000014,0x00000023,
0x00000001,0x0004002b,0x00000006,0x00000025,0x00000000,0x0004002b,0x00000006,0x00000026,
0x3f800000,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,
0x0004003d,0x00000007,0x00000010,0x0000000f,0x00050041,0x00000011,0x00000012,0x0000000b,
0x0000000d,0x0003003e,0x00000012,0x00000010,0x0004003d,0x00000008,0x00000016,0x00000015,
0x00050041,0x00000017,0x00000018,0x0000000b,0x00000013,0x0003003e,0x00000018,0x00000016,
0x00050041,0x00000020,0x00000021,0x0000001f,0x0000000d,0x0004003d,0x0000001c,0x00000022,
0x00000021,0x0004003d,0x00000008,0x00000024,0x00000023,0x00050051,0x00000006,0x00000027,
0x00000024,0x00000000,0x00050051,0x00000006,0x00000028,0x00000024,0x00000001,0x00070050,
0x00000007,0x00000029,0x00000027,0x00000028,0x00000025,0x00000026,0x00050091,0x00000007,
0x0000002a,0x00000022,0x00000029,0x00050041,0x00000011,0x0000002b,0x0000001b,0x0000000d,
0x0003003e,0x0000002b,0x0000002a,0x000100fd,0x00010038
};
// glsl_shader.frag, compiled with:
// # glslangValidator -V -x -o glsl_shader.frag.u32 glsl_shader.frag
/*
#version 450 core
layout(location = 0) out vec4 fColor;
layout(set=0, binding=1) uniform sampler s;
layout(set=1, binding=0) uniform texture2D t;
layout(location = 0) in struct { vec4 Color; vec2 UV; } In;
void main()
{
fColor = In.Color * texture(sampler2D(t, s), In.UV.st);
}
*/
static uint32_t __glsl_shader_frag_spv[] =
{
0x07230203,0x00010000,0x00080007,0x00000023,0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000009,0x0000000d,0x00030010,
0x00000004,0x00000007,0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d,
0x00000000,0x00040005,0x00000009,0x6c6f4366,0x0000726f,0x00030005,0x0000000b,0x00000000,
0x00050006,0x0000000b,0x00000000,0x6f6c6f43,0x00000072,0x00040006,0x0000000b,0x00000001,
0x00005655,0x00030005,0x0000000d,0x00006e49,0x00030005,0x00000015,0x00000074,0x00030005,
0x00000019,0x00000073,0x00040047,0x00000009,0x0000001e,0x00000000,0x00040047,0x0000000d,
0x0000001e,0x00000000,0x00040047,0x00000015,0x00000022,0x00000001,0x00040047,0x00000015,
0x00000021,0x00000000,0x00040047,0x00000019,0x00000022,0x00000000,0x00040047,0x00000019,
0x00000021,0x00000001,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,
0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040020,0x00000008,
0x00000003,0x00000007,0x0004003b,0x00000008,0x00000009,0x00000003,0x00040017,0x0000000a,
0x00000006,0x00000002,0x0004001e,0x0000000b,0x00000007,0x0000000a,0x00040020,0x0000000c,
0x00000001,0x0000000b,0x0004003b,0x0000000c,0x0000000d,0x00000001,0x00040015,0x0000000e,
0x00000020,0x00000001,0x0004002b,0x0000000e,0x0000000f,0x00000000,0x00040020,0x00000010,
0x00000001,0x00000007,0x00090019,0x00000013,0x00000006,0x00000001,0x00000000,0x00000000,
0x00000000,0x00000001,0x00000000,0x00040020,0x00000014,0x00000000,0x00000013,0x0004003b,
0x00000014,0x00000015,0x00000000,0x0002001a,0x00000017,0x00040020,0x00000018,0x00000000,
0x00000017,0x0004003b,0x00000018,0x00000019,0x00000000,0x0003001b,0x0000001b,0x00000013,
0x0004002b,0x0000000e,0x0000001d,0x00000001,0x00040020,0x0000001e,0x00000001,0x0000000a,
0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x00050041,
0x00000010,0x00000011,0x0000000d,0x0000000f,0x0004003d,0x00000007,0x00000012,0x00000011,
0x0004003d,0x00000013,0x00000016,0x00000015,0x0004003d,0x00000017,0x0000001a,0x00000019,
0x00050056,0x0000001b,0x0000001c,0x00000016,0x0000001a,0x00050041,0x0000001e,0x0000001f,
0x0000000d,0x0000001d,0x0004003d,0x0000000a,0x00000020,0x0000001f,0x00050057,0x00000007,
0x00000021,0x0000001c,0x00000020,0x00050085,0x00000007,0x00000022,0x00000012,0x00000021,
0x0003003e,0x00000009,0x00000022,0x000100fd,0x00010038
};
static void SafeRelease(ImDrawIdx*& res)
{
if (res)
delete[] res;
res = NULL;
}
static void SafeRelease(ImDrawVert*& res)
{
if (res)
delete[] res;
res = NULL;
}
static void SafeRelease(WGPUBindGroupLayout& res)
{
if (res)
wgpuBindGroupLayoutRelease(res);
res = NULL;
}
static void SafeRelease(WGPUBindGroup& res)
{
if (res)
wgpuBindGroupRelease(res);
res = NULL;
}
static void SafeRelease(WGPUBuffer& res)
{
if (res)
wgpuBufferRelease(res);
res = NULL;
}
static void SafeRelease(WGPURenderPipeline& res)
{
if (res)
wgpuRenderPipelineRelease(res);
res = NULL;
}
static void SafeRelease(WGPUSampler& res)
{
if (res)
wgpuSamplerRelease(res);
res = NULL;
}
static void SafeRelease(WGPUShaderModule& res)
{
if (res)
wgpuShaderModuleRelease(res);
res = NULL;
}
static void SafeRelease(WGPUTextureView& res)
{
if (res)
wgpuTextureViewRelease(res);
res = NULL;
}
static void SafeRelease(WGPUTexture& res)
{
if (res)
wgpuTextureRelease(res);
res = NULL;
}
static void SafeRelease(RenderResources& res)
{
SafeRelease(res.FontTexture);
SafeRelease(res.FontTextureView);
SafeRelease(res.Sampler);
SafeRelease(res.Uniforms);
SafeRelease(res.CommonBindGroup);
SafeRelease(res.ImageBindGroupLayout);
SafeRelease(res.ImageBindGroup);
};
static void SafeRelease(FrameResources& res)
{
SafeRelease(res.IndexBuffer);
SafeRelease(res.VertexBuffer);
SafeRelease(res.IndexBufferHost);
SafeRelease(res.VertexBufferHost);
}
static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModule(uint32_t* binary_data, uint32_t binary_data_size)
{
WGPUShaderModuleSPIRVDescriptor spirv_desc = {};
spirv_desc.chain.sType = WGPUSType_ShaderModuleSPIRVDescriptor;
spirv_desc.codeSize = binary_data_size;
spirv_desc.code = binary_data;
WGPUShaderModuleDescriptor desc;
desc.nextInChain = reinterpret_cast<WGPUChainedStruct*>(&spirv_desc);
WGPUProgrammableStageDescriptor stage_desc = {};
stage_desc.module = wgpuDeviceCreateShaderModule(g_wgpuDevice, &desc);
stage_desc.entryPoint = "main";
return stage_desc;
}
static WGPUBindGroup ImGui_ImplWGPU_CreateImageBindGroup(WGPUBindGroupLayout layout, WGPUTextureView texture)
{
WGPUBindGroupEntry image_bg_entries[] = { { 0, 0, 0, 0, 0, texture } };
WGPUBindGroupDescriptor image_bg_descriptor = {};
image_bg_descriptor.layout = layout;
image_bg_descriptor.entryCount = sizeof(image_bg_entries) / sizeof(WGPUBindGroupEntry);
image_bg_descriptor.entries = image_bg_entries;
return wgpuDeviceCreateBindGroup(g_wgpuDevice, &image_bg_descriptor);
}
static void ImGui_ImplWGPU_SetupRenderState(ImDrawData* draw_data, WGPURenderPassEncoder ctx, FrameResources* fr)
{
// Setup orthographic projection matrix into our constant buffer
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right).
{
float L = draw_data->DisplayPos.x;
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
float T = draw_data->DisplayPos.y;
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
float mvp[4][4] =
{
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
{ 0.0f, 0.0f, 0.5f, 0.0f },
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
};
wgpuQueueWriteBuffer(wgpuDeviceGetDefaultQueue(g_wgpuDevice), g_resources.Uniforms, 0, mvp, sizeof(mvp));
}
// Setup viewport
wgpuRenderPassEncoderSetViewport(ctx, 0, 0, draw_data->DisplaySize.x, draw_data->DisplaySize.y, 0, 1);
// Bind shader and vertex buffers
unsigned int stride = sizeof(ImDrawVert);
unsigned int offset = 0;
wgpuRenderPassEncoderSetVertexBuffer(ctx, 0, fr->VertexBuffer, offset, fr->VertexBufferSize * stride);
wgpuRenderPassEncoderSetIndexBuffer(ctx, fr->IndexBuffer, sizeof(ImDrawIdx) == 2 ? WGPUIndexFormat_Uint16 : WGPUIndexFormat_Uint32, 0, fr->IndexBufferSize * sizeof(ImDrawIdx));
wgpuRenderPassEncoderSetPipeline(ctx, g_pipelineState);
wgpuRenderPassEncoderSetBindGroup(ctx, 0, g_resources.CommonBindGroup, 0, NULL);
// Setup blend factor
WGPUColor blend_color = { 0.f, 0.f, 0.f, 0.f };
wgpuRenderPassEncoderSetBlendColor(ctx, &blend_color);
}
// Render function
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder pass_encoder)
{
// Avoid rendering when minimized
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
return;
// FIXME: Assuming that this only gets called once per frame!
// If not, we can't just re-allocate the IB or VB, we'll have to do a proper allocator.
g_frameIndex = g_frameIndex + 1;
FrameResources* fr = &g_pFrameResources[g_frameIndex % g_numFramesInFlight];
// Create and grow vertex/index buffers if needed
if (fr->VertexBuffer == NULL || fr->VertexBufferSize < draw_data->TotalVtxCount)
{
SafeRelease(fr->VertexBuffer);
SafeRelease(fr->VertexBufferHost);
fr->VertexBufferSize = draw_data->TotalVtxCount + 5000;
WGPUBufferDescriptor vb_desc =
{
NULL,
"Dear ImGui Vertex buffer",
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex,
fr->VertexBufferSize * sizeof(ImDrawVert),
false
};
fr->VertexBuffer = wgpuDeviceCreateBuffer(g_wgpuDevice, &vb_desc);
if (!fr->VertexBuffer)
return;
fr->VertexBufferHost = new ImDrawVert[fr->VertexBufferSize];
}
if (fr->IndexBuffer == NULL || fr->IndexBufferSize < draw_data->TotalIdxCount)
{
SafeRelease(fr->IndexBuffer);
SafeRelease(fr->IndexBufferHost);
fr->IndexBufferSize = draw_data->TotalIdxCount + 10000;
WGPUBufferDescriptor ib_desc =
{
NULL,
"Dear ImGui Index buffer",
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Index,
fr->IndexBufferSize * sizeof(ImDrawIdx),
false
};
fr->IndexBuffer = wgpuDeviceCreateBuffer(g_wgpuDevice, &ib_desc);
if (!fr->IndexBuffer)
return;
fr->IndexBufferHost = new ImDrawIdx[fr->IndexBufferSize];
}
// Upload vertex/index data into a single contiguous GPU buffer
ImDrawVert* vtx_dst = (ImDrawVert*)fr->VertexBufferHost;
ImDrawIdx* idx_dst = (ImDrawIdx*)fr->IndexBufferHost;
for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
vtx_dst += cmd_list->VtxBuffer.Size;
idx_dst += cmd_list->IdxBuffer.Size;
}
int64_t vb_write_size = ((char*)vtx_dst - (char*)fr->VertexBufferHost + 3) & ~3;
int64_t ib_write_size = ((char*)idx_dst - (char*)fr->IndexBufferHost + 3) & ~3;
wgpuQueueWriteBuffer(wgpuDeviceGetDefaultQueue(g_wgpuDevice), fr->VertexBuffer, 0, fr->VertexBufferHost, vb_write_size);
wgpuQueueWriteBuffer(wgpuDeviceGetDefaultQueue(g_wgpuDevice), fr->IndexBuffer, 0, fr->IndexBufferHost, ib_write_size);
// Setup desired render state
ImGui_ImplWGPU_SetupRenderState(draw_data, pass_encoder, fr);
// Render command lists
// (Because we merged all buffers into a single one, we maintain our own offset into them)
int global_vtx_offset = 0;
int global_idx_offset = 0;
ImVec2 clip_off = draw_data->DisplayPos;
for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback != NULL)
{
// User callback, registered via ImDrawList::AddCallback()
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplWGPU_SetupRenderState(draw_data, pass_encoder, fr);
else
pcmd->UserCallback(cmd_list, pcmd);
}
else
{
// Bind custom texture
auto bind_group = g_resources.ImageBindGroups.GetVoidPtr(ImHashData(&pcmd->TextureId, sizeof(ImTextureID)));
if (bind_group)
{
wgpuRenderPassEncoderSetBindGroup(pass_encoder, 1, (WGPUBindGroup)bind_group, 0, NULL);
}
else
{
WGPUBindGroup image_bind_group = ImGui_ImplWGPU_CreateImageBindGroup(g_resources.ImageBindGroupLayout, (WGPUTextureView)pcmd->TextureId);
g_resources.ImageBindGroups.SetVoidPtr(ImHashData(&pcmd->TextureId, sizeof(ImTextureID)), image_bind_group);
wgpuRenderPassEncoderSetBindGroup(pass_encoder, 1, image_bind_group, 0, NULL);
}
// Apply Scissor, Bind texture, Draw
uint32_t clip_rect[4];
clip_rect[0] = static_cast<uint32_t>(pcmd->ClipRect.x - clip_off.x);
clip_rect[1] = static_cast<uint32_t>(pcmd->ClipRect.y - clip_off.y);
clip_rect[2] = static_cast<uint32_t>(pcmd->ClipRect.z - clip_off.x);
clip_rect[3] = static_cast<uint32_t>(pcmd->ClipRect.w - clip_off.y);
wgpuRenderPassEncoderSetScissorRect(pass_encoder, clip_rect[0], clip_rect[1], clip_rect[2] - clip_rect[0], clip_rect[3] - clip_rect[1]);
wgpuRenderPassEncoderDrawIndexed(pass_encoder, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
}
}
global_idx_offset += cmd_list->IdxBuffer.Size;
global_vtx_offset += cmd_list->VtxBuffer.Size;
}
}
static WGPUBuffer ImGui_ImplWGPU_CreateBufferFromData(const WGPUDevice& device, const void* data, uint64_t size, WGPUBufferUsage usage)
{
WGPUBufferDescriptor descriptor = {};
descriptor.size = size;
descriptor.usage = usage | WGPUBufferUsage_CopyDst;
WGPUBuffer buffer = wgpuDeviceCreateBuffer(device, &descriptor);
WGPUQueue queue = wgpuDeviceGetDefaultQueue(g_wgpuDevice);
wgpuQueueWriteBuffer(queue, buffer, 0, data, size);
return buffer;
}
static void ImGui_ImplWGPU_CreateFontsTexture()
{
// Build texture atlas
ImGuiIO& io = ImGui::GetIO();
unsigned char* pixels;
int width, height, size_pp;
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height, &size_pp);
// Upload texture to graphics system
{
WGPUTextureDescriptor tex_desc = {};
tex_desc.label = "Dear ImGui Font Texture";
tex_desc.dimension = WGPUTextureDimension_2D;
tex_desc.size.width = width;
tex_desc.size.height = height;
tex_desc.size.depth = 1;
tex_desc.sampleCount = 1;
tex_desc.format = WGPUTextureFormat_RGBA8Unorm;
tex_desc.mipLevelCount = 1;
tex_desc.usage = WGPUTextureUsage_CopyDst | WGPUTextureUsage_Sampled;
g_resources.FontTexture = wgpuDeviceCreateTexture(g_wgpuDevice, &tex_desc);
WGPUTextureViewDescriptor tex_view_desc = {};
tex_view_desc.format = WGPUTextureFormat_RGBA8Unorm;
tex_view_desc.dimension = WGPUTextureViewDimension_2D;
tex_view_desc.baseMipLevel = 0;
tex_view_desc.mipLevelCount = 1;
tex_view_desc.baseArrayLayer = 0;
tex_view_desc.arrayLayerCount = 1;
tex_view_desc.aspect = WGPUTextureAspect_All;
g_resources.FontTextureView = wgpuTextureCreateView(g_resources.FontTexture, &tex_view_desc);
}
// Upload texture data
{
WGPUBuffer staging_buffer = ImGui_ImplWGPU_CreateBufferFromData(g_wgpuDevice, pixels, (uint32_t)(width * size_pp * height), WGPUBufferUsage_CopySrc);
WGPUBufferCopyView bufferCopyView = {};
bufferCopyView.buffer = staging_buffer;
bufferCopyView.layout.offset = 0;
bufferCopyView.layout.bytesPerRow = width * size_pp;
bufferCopyView.layout.rowsPerImage = height;
WGPUTextureCopyView textureCopyView = {};
textureCopyView.texture = g_resources.FontTexture;
textureCopyView.mipLevel = 0;
textureCopyView.origin = { 0, 0, 0 };
#if !defined(__EMSCRIPTEN__) || HAS_EMSCRIPTEN_VERSION(2, 0, 14)
textureCopyView.aspect = WGPUTextureAspect_All;
#endif
WGPUExtent3D copySize = { (uint32_t)width, (uint32_t)height, 1 };
WGPUCommandEncoderDescriptor enc_desc = {};
WGPUCommandEncoder encoder = wgpuDeviceCreateCommandEncoder(g_wgpuDevice, &enc_desc);
wgpuCommandEncoderCopyBufferToTexture(encoder, &bufferCopyView, &textureCopyView, &copySize);
WGPUCommandBufferDescriptor cmd_buf_desc = {};
WGPUCommandBuffer copy = wgpuCommandEncoderFinish(encoder, &cmd_buf_desc);
WGPUQueue queue = wgpuDeviceGetDefaultQueue(g_wgpuDevice);
wgpuQueueSubmit(queue, 1, &copy);
wgpuCommandEncoderRelease(encoder);
wgpuBufferRelease(staging_buffer);
}
// Create the associated sampler
{
WGPUSamplerDescriptor sampler_desc = {};
sampler_desc.minFilter = WGPUFilterMode_Linear;
sampler_desc.magFilter = WGPUFilterMode_Linear;
sampler_desc.mipmapFilter = WGPUFilterMode_Linear;
sampler_desc.addressModeU = WGPUAddressMode_Repeat;
sampler_desc.addressModeV = WGPUAddressMode_Repeat;
sampler_desc.addressModeW = WGPUAddressMode_Repeat;
#if !defined(__EMSCRIPTEN__) || HAS_EMSCRIPTEN_VERSION(2, 0, 14)
sampler_desc.maxAnisotropy = 1;
#endif
g_resources.Sampler = wgpuDeviceCreateSampler(g_wgpuDevice, &sampler_desc);
}
// Store our identifier
static_assert(sizeof(ImTextureID) >= sizeof(g_resources.FontTexture), "Can't pack descriptor handle into TexID, 32-bit not supported yet.");
io.Fonts->SetTexID((ImTextureID)g_resources.FontTextureView);
}
static void ImGui_ImplWGPU_CreateUniformBuffer()
{
WGPUBufferDescriptor ub_desc =
{
NULL,
"Dear ImGui Uniform buffer",
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Uniform,
sizeof(Uniforms),
false
};
g_resources.Uniforms = wgpuDeviceCreateBuffer(g_wgpuDevice, &ub_desc);
}
bool ImGui_ImplWGPU_CreateDeviceObjects()
{
if (!g_wgpuDevice)
return false;
if (g_pipelineState)
ImGui_ImplWGPU_InvalidateDeviceObjects();
// Create render pipeline
WGPURenderPipelineDescriptor graphics_pipeline_desc = {};
graphics_pipeline_desc.primitiveTopology = WGPUPrimitiveTopology_TriangleList;
graphics_pipeline_desc.sampleCount = 1;
graphics_pipeline_desc.sampleMask = UINT_MAX;
WGPUBindGroupLayoutEntry common_bg_layout_entries[2] = {};
common_bg_layout_entries[0].binding = 0;
common_bg_layout_entries[0].visibility = WGPUShaderStage_Vertex;
#if !defined(__EMSCRIPTEN__) || HAS_EMSCRIPTEN_VERSION(2, 0, 14)
common_bg_layout_entries[0].buffer.type = WGPUBufferBindingType_Uniform;
#else
common_bg_layout_entries[0].type = WGPUBindingType_UniformBuffer;
#endif
common_bg_layout_entries[1].binding = 1;
common_bg_layout_entries[1].visibility = WGPUShaderStage_Fragment;
#if !defined(__EMSCRIPTEN__) || HAS_EMSCRIPTEN_VERSION(2, 0, 14)
common_bg_layout_entries[1].sampler.type = WGPUSamplerBindingType_Filtering;
#else
common_bg_layout_entries[1].type = WGPUBindingType_Sampler;
#endif
WGPUBindGroupLayoutEntry image_bg_layout_entries[1] = {};
image_bg_layout_entries[0].binding = 0;
image_bg_layout_entries[0].visibility = WGPUShaderStage_Fragment;
#if !defined(__EMSCRIPTEN__) || HAS_EMSCRIPTEN_VERSION(2, 0, 14)
image_bg_layout_entries[0].texture.sampleType = WGPUTextureSampleType_Float;
image_bg_layout_entries[0].texture.viewDimension = WGPUTextureViewDimension_2D;
#else
image_bg_layout_entries[0].type = WGPUBindingType_SampledTexture;
#endif
WGPUBindGroupLayoutDescriptor common_bg_layout_desc = {};
common_bg_layout_desc.entryCount = 2;
common_bg_layout_desc.entries = common_bg_layout_entries;
WGPUBindGroupLayoutDescriptor image_bg_layout_desc = {};
image_bg_layout_desc.entryCount = 1;
image_bg_layout_desc.entries = image_bg_layout_entries;
WGPUBindGroupLayout bg_layouts[2];
bg_layouts[0] = wgpuDeviceCreateBindGroupLayout(g_wgpuDevice, &common_bg_layout_desc);
bg_layouts[1] = wgpuDeviceCreateBindGroupLayout(g_wgpuDevice, &image_bg_layout_desc);
WGPUPipelineLayoutDescriptor layout_desc = {};
layout_desc.bindGroupLayoutCount = 2;
layout_desc.bindGroupLayouts = bg_layouts;
graphics_pipeline_desc.layout = wgpuDeviceCreatePipelineLayout(g_wgpuDevice, &layout_desc);
// Create the vertex shader
WGPUProgrammableStageDescriptor vertex_shader_desc = ImGui_ImplWGPU_CreateShaderModule(__glsl_shader_vert_spv, sizeof(__glsl_shader_vert_spv) / sizeof(uint32_t));
graphics_pipeline_desc.vertexStage = vertex_shader_desc;
// Vertex input configuration
WGPUVertexAttributeDescriptor attribute_binding_desc[] =
{
{ WGPUVertexFormat_Float2, (uint64_t)IM_OFFSETOF(ImDrawVert, pos), 0 },
{ WGPUVertexFormat_Float2, (uint64_t)IM_OFFSETOF(ImDrawVert, uv), 1 },
{ WGPUVertexFormat_UChar4Norm, (uint64_t)IM_OFFSETOF(ImDrawVert, col), 2 },
};
WGPUVertexBufferLayoutDescriptor buffer_binding_desc;
buffer_binding_desc.arrayStride = sizeof(ImDrawVert);
buffer_binding_desc.stepMode = WGPUInputStepMode_Vertex;
buffer_binding_desc.attributeCount = 3;
buffer_binding_desc.attributes = attribute_binding_desc;
WGPUVertexStateDescriptor vertex_state_desc = {};
vertex_state_desc.indexFormat = WGPUIndexFormat_Undefined;
vertex_state_desc.vertexBufferCount = 1;
vertex_state_desc.vertexBuffers = &buffer_binding_desc;
graphics_pipeline_desc.vertexState = &vertex_state_desc;
// Create the pixel shader
WGPUProgrammableStageDescriptor pixel_shader_desc = ImGui_ImplWGPU_CreateShaderModule(__glsl_shader_frag_spv, sizeof(__glsl_shader_frag_spv) / sizeof(uint32_t));
graphics_pipeline_desc.fragmentStage = &pixel_shader_desc;
// Create the blending setup
WGPUColorStateDescriptor color_state = {};
{
color_state.format = g_renderTargetFormat;
color_state.alphaBlend.operation = WGPUBlendOperation_Add;
color_state.alphaBlend.srcFactor = WGPUBlendFactor_SrcAlpha;
color_state.alphaBlend.dstFactor = WGPUBlendFactor_OneMinusSrcAlpha;
color_state.colorBlend.operation = WGPUBlendOperation_Add;
color_state.colorBlend.srcFactor = WGPUBlendFactor_SrcAlpha;
color_state.colorBlend.dstFactor = WGPUBlendFactor_OneMinusSrcAlpha;
color_state.writeMask = WGPUColorWriteMask_All;
graphics_pipeline_desc.colorStateCount = 1;
graphics_pipeline_desc.colorStates = &color_state;
graphics_pipeline_desc.alphaToCoverageEnabled = false;
}
// Create the rasterizer state
WGPURasterizationStateDescriptor raster_desc = {};
{
raster_desc.cullMode = WGPUCullMode_None;
raster_desc.frontFace = WGPUFrontFace_CW;
raster_desc.depthBias = 0;
raster_desc.depthBiasClamp = 0;
raster_desc.depthBiasSlopeScale = 0;
graphics_pipeline_desc.rasterizationState = &raster_desc;
}
// Create depth-stencil State
WGPUDepthStencilStateDescriptor depth_desc = {};
{
// Configure disabled state
depth_desc.format = WGPUTextureFormat_Undefined;
depth_desc.depthWriteEnabled = true;
depth_desc.depthCompare = WGPUCompareFunction_Always;
depth_desc.stencilReadMask = 0;
depth_desc.stencilWriteMask = 0;
depth_desc.stencilBack.compare = WGPUCompareFunction_Always;
depth_desc.stencilBack.failOp = WGPUStencilOperation_Keep;
depth_desc.stencilBack.depthFailOp = WGPUStencilOperation_Keep;
depth_desc.stencilBack.passOp = WGPUStencilOperation_Keep;
depth_desc.stencilFront.compare = WGPUCompareFunction_Always;
depth_desc.stencilFront.failOp = WGPUStencilOperation_Keep;
depth_desc.stencilFront.depthFailOp = WGPUStencilOperation_Keep;
depth_desc.stencilFront.passOp = WGPUStencilOperation_Keep;
// No depth buffer corresponds to no configuration
graphics_pipeline_desc.depthStencilState = NULL;
}
g_pipelineState = wgpuDeviceCreateRenderPipeline(g_wgpuDevice, &graphics_pipeline_desc);
ImGui_ImplWGPU_CreateFontsTexture();
ImGui_ImplWGPU_CreateUniformBuffer();
// Create resource bind group
WGPUBindGroupEntry common_bg_entries[] =
{
{ 0, g_resources.Uniforms, 0, sizeof(Uniforms), 0, 0 },
{ 1, 0, 0, 0, g_resources.Sampler, 0 },
};
WGPUBindGroupDescriptor common_bg_descriptor = {};
common_bg_descriptor.layout = bg_layouts[0];
common_bg_descriptor.entryCount = sizeof(common_bg_entries) / sizeof(WGPUBindGroupEntry);
common_bg_descriptor.entries = common_bg_entries;
g_resources.CommonBindGroup = wgpuDeviceCreateBindGroup(g_wgpuDevice, &common_bg_descriptor);
g_resources.ImageBindGroupLayout = bg_layouts[1];
WGPUBindGroup image_bind_group = ImGui_ImplWGPU_CreateImageBindGroup(bg_layouts[1], g_resources.FontTextureView);
g_resources.ImageBindGroup = image_bind_group;
g_resources.ImageBindGroups.SetVoidPtr(ImHashData(&g_resources.FontTextureView, sizeof(ImTextureID)), image_bind_group);
SafeRelease(vertex_shader_desc.module);
SafeRelease(pixel_shader_desc.module);
SafeRelease(bg_layouts[0]);
return true;
}
void ImGui_ImplWGPU_InvalidateDeviceObjects()
{
if (!g_wgpuDevice)
return;
SafeRelease(g_pipelineState);
SafeRelease(g_resources);
ImGuiIO& io = ImGui::GetIO();
io.Fonts->SetTexID(NULL); // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
for (unsigned int i = 0; i < g_numFramesInFlight; i++)
SafeRelease(g_pFrameResources[i]);
}
bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextureFormat rt_format)
{
// Setup back-end capabilities flags
ImGuiIO& io = ImGui::GetIO();
io.BackendRendererName = "imgui_impl_webgpu";
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
g_wgpuDevice = device;
g_renderTargetFormat = rt_format;
g_pFrameResources = new FrameResources[num_frames_in_flight];
g_numFramesInFlight = num_frames_in_flight;
g_frameIndex = UINT_MAX;
g_resources.FontTexture = NULL;
g_resources.FontTextureView = NULL;
g_resources.Sampler = NULL;
g_resources.Uniforms = NULL;
g_resources.CommonBindGroup = NULL;
g_resources.ImageBindGroupLayout = NULL;
g_resources.ImageBindGroups.Data.reserve(100);
g_resources.ImageBindGroup = NULL;
// Create buffers with a default size (they will later be grown as needed)
for (int i = 0; i < num_frames_in_flight; i++)
{
FrameResources* fr = &g_pFrameResources[i];
fr->IndexBuffer = NULL;
fr->VertexBuffer = NULL;
fr->IndexBufferHost = NULL;
fr->VertexBufferHost = NULL;
fr->IndexBufferSize = 10000;
fr->VertexBufferSize = 5000;
}
return true;
}
void ImGui_ImplWGPU_Shutdown()
{
ImGui_ImplWGPU_InvalidateDeviceObjects();
delete[] g_pFrameResources;
g_pFrameResources = NULL;
g_wgpuDevice = NULL;
g_numFramesInFlight = 0;
g_frameIndex = UINT_MAX;
}
void ImGui_ImplWGPU_NewFrame()
{
if (!g_pipelineState)
ImGui_ImplWGPU_CreateDeviceObjects();
}

View File

@ -0,0 +1,24 @@
// dear imgui: Renderer for WebGPU
// This needs to be used along with a Platform Binding (e.g. GLFW)
// (Please note that WebGPU is currently experimental, will not run on non-beta browsers, and may break.)
// Implemented features:
// [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID!
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
// You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Read online: https://github.com/ocornut/imgui/tree/master/docs
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#include <webgpu/webgpu.h>
IMGUI_IMPL_API bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextureFormat rt_format);
IMGUI_IMPL_API void ImGui_ImplWGPU_Shutdown();
IMGUI_IMPL_API void ImGui_ImplWGPU_NewFrame();
IMGUI_IMPL_API void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder pass_encoder);
// Use if you want to reset your rendering device without losing Dear ImGui state.
IMGUI_IMPL_API void ImGui_ImplWGPU_InvalidateDeviceObjects();
IMGUI_IMPL_API bool ImGui_ImplWGPU_CreateDeviceObjects();

View File

@ -19,19 +19,16 @@
#include <windows.h>
#include <tchar.h>
// Using XInput library for gamepad (with recent Windows SDK this may leads to executables which won't run on Windows 7)
// Using XInput for gamepad (will load DLL dynamically)
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
#include <XInput.h>
#else
#define IMGUI_IMPL_WIN32_DISABLE_LINKING_XINPUT
#endif
#if defined(_MSC_VER) && !defined(IMGUI_IMPL_WIN32_DISABLE_LINKING_XINPUT)
#pragma comment(lib, "xinput")
//#pragma comment(lib, "Xinput9_1_0")
typedef DWORD (WINAPI *PFN_XInputGetCapabilities)(DWORD, DWORD, XINPUT_CAPABILITIES*);
typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*);
#endif
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2021-01-25: Inputs: Dynamically loading XInput DLL.
// 2020-12-04: Misc: Fixed setting of io.DisplaySize to invalid/uninitialized data when after hwnd has been closed.
// 2020-03-03: Inputs: Calling AddInputCharacterUTF16() to support surrogate pairs leading to codepoint >= 0x10000 (for more complete CJK inputs)
// 2020-02-17: Added ImGui_ImplWin32_EnableDpiAwareness(), ImGui_ImplWin32_GetDpiScaleForHwnd(), ImGui_ImplWin32_GetDpiScaleForMonitor() helper functions.
@ -65,6 +62,13 @@ static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_COUNT;
static bool g_HasGamepad = false;
static bool g_WantUpdateHasGamepad = true;
// XInput DLL and functions
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
static HMODULE g_XInputDLL = NULL;
static PFN_XInputGetCapabilities g_XInputGetCapabilities = NULL;
static PFN_XInputGetState g_XInputGetState = NULL;
#endif
// Functions
bool ImGui_ImplWin32_Init(void* hwnd)
{
@ -105,12 +109,46 @@ bool ImGui_ImplWin32_Init(void* hwnd)
io.KeyMap[ImGuiKey_Y] = 'Y';
io.KeyMap[ImGuiKey_Z] = 'Z';
// Dynamically load XInput library
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
const char* xinput_dll_names[] =
{
"xinput1_4.dll", // Windows 8+
"xinput1_3.dll", // DirectX SDK
"xinput9_1_0.dll", // Windows Vista, Windows 7
"xinput1_2.dll", // DirectX SDK
"xinput1_1.dll" // DirectX SDK
};
for (int n = 0; n < IM_ARRAYSIZE(xinput_dll_names); n++)
if (HMODULE dll = ::LoadLibraryA(xinput_dll_names[n]))
{
g_XInputDLL = dll;
g_XInputGetCapabilities = (PFN_XInputGetCapabilities)::GetProcAddress(dll, "XInputGetCapabilities");
g_XInputGetState = (PFN_XInputGetState)::GetProcAddress(dll, "XInputGetState");
break;
}
#endif // IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
return true;
}
void ImGui_ImplWin32_Shutdown()
{
g_hWnd = (HWND)0;
// Unload XInput library
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
if (g_XInputDLL)
::FreeLibrary(g_XInputDLL);
g_XInputDLL = NULL;
g_XInputGetCapabilities = NULL;
g_XInputGetState = NULL;
#endif // IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
g_hWnd = NULL;
g_Time = 0;
g_TicksPerSecond = 0;
g_LastMouseCursor = ImGuiMouseCursor_COUNT;
g_HasGamepad = false;
g_WantUpdateHasGamepad = true;
}
static bool ImGui_ImplWin32_UpdateMouseCursor()
@ -181,13 +219,13 @@ static void ImGui_ImplWin32_UpdateGamepads()
if (g_WantUpdateHasGamepad)
{
XINPUT_CAPABILITIES caps;
g_HasGamepad = (XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &caps) == ERROR_SUCCESS);
g_HasGamepad = g_XInputGetCapabilities ? (g_XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &caps) == ERROR_SUCCESS) : false;
g_WantUpdateHasGamepad = false;
}
XINPUT_STATE xinput_state;
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
if (g_HasGamepad && XInputGetState(0, &xinput_state) == ERROR_SUCCESS)
XINPUT_STATE xinput_state;
if (g_HasGamepad && g_XInputGetState && g_XInputGetState(0, &xinput_state) == ERROR_SUCCESS)
{
const XINPUT_GAMEPAD& gamepad = xinput_state.Gamepad;
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;

View File

@ -19,9 +19,8 @@ IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown();
IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame();
// Configuration
// - Disable gamepad support or linking with xinput.lib
// - Disable gamepad support
//#define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
//#define IMGUI_IMPL_WIN32_DISABLE_LINKING_XINPUT
// Win32 message handler your application need to call.
// - Intentionally commented out in a '#if 0' block to avoid dragging dependencies on <windows.h> from this helper.

View File

@ -56,7 +56,7 @@ List of Platforms Backends:
imgui_impl_osx.mm ; macOS native API (not as feature complete as glfw/sdl backends)
imgui_impl_sdl.cpp ; SDL2 (Windows, macOS, Linux, iOS, Android) https://www.libsdl.org
imgui_impl_win32.cpp ; Win32 native API (Windows)
imgui_impl_glut.cpp ; GLUT/FreeGLUT (absolutely not recommended in 2020!)
imgui_impl_glut.cpp ; GLUT/FreeGLUT (this is prehistoric software and absolutely not recommended today!)
List of Renderer Backends:
@ -68,6 +68,7 @@ List of Renderer Backends:
imgui_impl_opengl2.cpp ; OpenGL 2 (legacy, fixed pipeline <- don't use with modern OpenGL context)
imgui_impl_opengl3.cpp ; OpenGL 3/4, OpenGL ES 2, OpenGL ES 3 (modern programmable pipeline)
imgui_impl_vulkan.cpp ; Vulkan
imgui_impl_wgpu.cpp ; WebGPU
List of high-level Frameworks Backends (combining Platform + Renderer):
@ -79,35 +80,7 @@ The [example_emscripten_opengl3](https://github.com/ocornut/imgui/tree/master/ex
### Backends for third-party frameworks, graphics API or other languages
See https://github.com/ocornut/imgui/wiki/Bindings
- AGS/Adventure Game Studio
- Amethyst
- bsf
- Cinder
- Cocos2d-x
- Diligent Engine
- Flexium,
- GML/Game Maker Studio2
- GTK3+OpenGL3
- Irrlicht Engine
- LÖVE+LUA
- Magnum
- NanoRT
- Nim Game Lib,
- Ogre
- openFrameworks
- OSG/OpenSceneGraph
- Orx
- px_render
- Qt/QtDirect3D
- SFML
- Sokol
- Unity
- Unreal Engine 4
- vtk
- Win32 GDI
etc.
See https://github.com/ocornut/imgui/wiki/Bindings for the full list.
### Recommended Backends

View File

@ -32,14 +32,97 @@ HOW TO UPDATE?
-----------------------------------------------------------------------
VERSION 1.80 (In Progress)
VERSION 1.81 (Released 2021-02-10)
-----------------------------------------------------------------------
Breaking Changes:
- Added imgui_tables.cpp file! Manually constructed project files will need the new file added!
- ListBox helpers:
- Renamed ListBoxHeader(const char* label, ImVec2 size) to BeginListBox().
- Renamed ListBoxFooter() to EndListBox().
- Removed ListBoxHeader(const char* label, int items_count, int height_in_items = -1) in favor of specifying size.
In the redirection function, made vertical padding consistent regardless of (items_count <= height_in_items) or not.
- Kept inline redirection function for all threes (will obsolete).
- imgui_freetype:
- Removed ImGuiFreeType::BuildFontAtlas(). Kept inline redirection function.
Prefer using '#define IMGUI_ENABLE_FREETYPE', but there's a runtime selection path available too.
- The shared extra flags parameters (very rarely used) are now stored in ImFontAtlas::FontBuilderFlags.
- Renamed ImFontConfig::RasterizerFlags (used by FreeType) to ImFontConfig::FontBuilderFlags.
- Renamed ImGuiFreeType::XXX flags to ImGuiFreeTypeBuilderFlags_XXX for consistency with other API.
Other Changes:
- Viewports Added ImGui::GetMainViewport() as a way to get the bounds and work area of the host display. (#3789, #1542)
- In 'master' branch or without multi-viewports feature enabled:
- GetMainViewport()->Pos is always == (0,0)
- GetMainViewport()->Size is always == io.DisplaySize
- In 'docking' branch and with the multi-viewports feature enabled:
- GetMainViewport() will return information from your host Platform Window.
- In the future, we will support a "no main viewport" mode and this may return bounds of your main monitor.
- For forward compatibility with multi-viewports/multi-monitors:
- Code using (0,0) as a way to signify "upper-left of the host window" should use GetMainViewport()->Pos.
- Code using io.DisplaySize as a way to signify "size of the host window" should use GetMainViewport()->Size.
- We are also exposing a work area in ImGuiViewport ('WorkPos', 'WorkSize' vs 'Pos', 'Size' for full area):
- For a Platform Window, the work area is generally the full area minus space used by menu-bars.
- For a Platform Monitor, the work area is generally the full area minus space used by task-bars.
- All of this has been the case in 'docking' branch for a long time. What we've done is merely merging
a small chunk of the multi-viewport logic into 'master' to standardize some concepts ahead of time.
- Tables: Fixed PopItemWidth() or multi-components items not restoring per-colum ItemWidth correctly. (#3760)
- Window: Fixed minor title bar text clipping issue when FramePadding is small/zero and there are no
close button in the window. (#3731)
- SliderInt: Fixed click/drag when v_min==v_max from setting the value to zero. (#3774) [@erwincoumans]
Would also repro with DragFloat() when using ImGuiSliderFlags_Logarithmic with v_min==v_max.
- Menus: Fixed an issue with child-menu auto sizing (issue introduced in 1.80 on 2021/01/25) (#3779)
- InputText: Fixed slightly off ScrollX tracking, noticeable with large values of FramePadding.x. (#3781)
- InputText: Multiline: Fixed padding/cliprect not precisely matching single-line version. (#3781)
- InputText: Multiline: Fixed FramePadding.y worth of vertical offset when aiming with mouse.
- ListBox: Tweaked default height calculation.
- Fonts: imgui_freetype: Facilitated using FreeType integration: [@Xipiryon, @ocornut]
- Use '#define IMGUI_ENABLE_FREETYPE' in imconfig.h should make it work with no other modifications
other than compiling misc/freetype/imgui_freetype.cpp and linking with FreeType.
- Use '#define IMGUI_ENABLE_STB_TRUETYPE' if you somehow need the stb_truetype rasterizer to be
compiled in along with the FreeType one, otherwise it is enabled by default.
- Fonts: imgui_freetype: Added support for colored glyphs as supported by Freetype 2.10+ (for .ttf using CPAL/COLR
tables only). Enable the ImGuiFreeTypeBuilderFlags_LoadColor on a given font. Atlas always output directly
as RGBA8 in this situation. Likely to make sense with IMGUI_USE_WCHAR32. (#3369) [@pshurgal]
- Fonts: Fixed CalcTextSize() width rounding so it behaves more like a ceil. This is in order for text wrapping
to have enough space when provided width precisely calculated with CalcTextSize().x. (#3776)
Note that the rounding of either positions and widths are technically undesirable (e.g. #3437, #791) but
variety of code is currently on it so we are first fixing current behavior before we'll eventually change it.
- Log/Capture: Fix various new line/spacing issue when logging widgets. [@Xipiryon, @ocornut]
- Log/Capture: Improved the ASCII look of various widgets, making large dumps more easily human readable.
- ImDrawList: Fixed AddCircle()/AddCircleFilled() with (rad > 0.0f && rad < 1.0f && num_segments == 0). (#3738)
Would lead to a buffer read overflow.
- ImDrawList: Clarified PathArcTo() need for a_min <= a_max with an assert.
- ImDrawList: Fixed PathArcToFast() handling of a_min > a_max.
- Metrics: Back-ported "Viewports" debug visualizer from 'docking' branch.
- Demo: Added 'Examples->Fullscreen Window' demo using GetMainViewport() values. (#3789)
- Demo: 'Simple Overlay' demo now moves under main menu-bar (if any) using GetMainViewport()'s work area.
- Backends: Win32: Dynamically loading XInput DLL instead of linking with it, facilitate compiling with
old WindowSDK versions or running on Windows 7. (#3646, #3645, #3248, #2716) [@Demonese]
- Backends: Vulkan: Add support for custom Vulkan function loader and VK_NO_PROTOTYPES. (#3759, #3227) [@Hossein-Noroozpour]
User needs to call ImGui_ImplVulkan_LoadFunctions() with their custom loader prior to other functions.
- Backends: Metal: Fixed texture storage mode when building on Mac Catalyst. (#3748) [@Belinsky-L-V]
- Backends: OSX: Fixed mouse position not being reported when mouse buttons other than left one are down. (#3762) [@rokups]
- Backends: WebGPU: Added enderer backend for WebGPU support (imgui_impl_wgpu.cpp) (#3632) [@bfierz]
Please note that WebGPU is currently experimental, will not run on non-beta browsers, and may break.
- Examples: WebGPU: Added Emscripten+WebGPU example. (#3632) [@bfierz]
- Backends: GLFW: Added ImGui_ImplGlfw_InitForOther() initialization call to use with non OpenGL API. (#3632)
-----------------------------------------------------------------------
VERSION 1.80 (Released 2021-01-21)
-----------------------------------------------------------------------
Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.80
Breaking Changes:
- Added imgui_tables.cpp file! Manually constructed project files will need the new file added! (#3740)
- Backends: moved all backends files (imgui_impl_XXXX.cpp, imgui_impl_XXXX.h) from examples/ to backends/. (#3513)
- Removed redirecting functions/enums names that were marked obsolete in 1.60 (April 2017):
- Renamed ImDrawList::AddBezierCurve() to ImDrawList::AddBezierCubic(). Kept inline redirection function (will obsolete).
- Renamed ImDrawList::PathBezierCurveTo() to ImDrawList::PathBezierCubicCurveTo(). Kept inline redirection function (will obsolete).
- Removed redirecting functions/enums names that were marked obsolete in 1.60 (April 2018):
- io.RenderDrawListsFn pointer -> use ImGui::GetDrawData() value and call the render function of your backend
- ImGui::IsAnyWindowFocused() -> use ImGui::IsWindowFocused(ImGuiFocusedFlags_AnyWindow)
- ImGui::IsAnyWindowHovered() -> use ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow)
@ -48,46 +131,64 @@ Breaking Changes:
- Removed redirecting functions/enums names that were marked obsolete in 1.61 (May 2018):
- InputFloat (... int decimal_precision ...) -> use InputFloat (... const char* format ...) with format = "%.Xf" where X was value for decimal_precision.
- same for InputFloat2()/InputFloat3()/InputFloat4() variants taking a `int decimal_precision` parameter.
- Removed redirecting functions/enums names that were marked obsolete in 1.63 (August 2018):
- ImGui::IsItemDeactivatedAfterChange() -> use ImGui::IsItemDeactivatedAfterEdit().
- ImGuiCol_ModalWindowDarkening -> use ImGuiCol_ModalWindowDimBg
- ImGuiInputTextCallback -> use ImGuiTextEditCallback
- ImGuiInputTextCallbackData -> use ImGuiTextEditCallbackData
- If you were still using the old names, while you are cleaning up, considering enabling
IMGUI_DISABLE_OBSOLETE_FUNCTIONS in imconfig.h even temporarily to have a pass at finding
and removing up old API calls, if any remaining.
- Columns: renamed undocumented/internals ImGuiColumnsFlags_* to ImGuiOldColumnFlags_* in prevision of
incoming Tables API. Keep redirection enums (will obsolete). (#125, #513, #913, #1204, #1444, #2142, #2707)
- Renamed io.ConfigWindowsMemoryCompactTimer to io.ConfigMemoryCompactTimer as the feature will apply
- Internals: Columns: renamed undocumented/internals ImGuiColumnsFlags_* to ImGuiOldColumnFlags_* to reduce
confusion with Tables API. Keep redirection enums (will obsolete). (#125, #513, #913, #1204, #1444, #2142, #2707)
- Renamed io.ConfigWindowsMemoryCompactTimer to io.ConfigMemoryCompactTimer as the feature now applies
to other data structures. (#2636)
Other Changes:
- Tables: added new Tables Beta API as a replacement for old Columns. (#2957, #125)
Check out 'Demo->Tables' for many demos + API comments in imgui.h for details.
- Added 16 functions: BeginTable(), EndTable(),
TableNextRow(), TableNextColumn(), TableSetColumnIndex(), TableGetColumnIndex(), TableGetRowIndex(),
TableSetupColumn(), TableSetupScrollFreeze(),
TableHeadersRow(), TableHeader(), TableSetBgColor(), TableGetSortSpecs(),
TableGetColumnCount(), TableGetColumnName(), TableGetColumnFlags().
- Added 2 structures: ImGuiTableSortSpecs, ImGuiTableColumnSortSpecs.
- Added 2 enums: ImGuiSortDirection, ImGuiTableBgTarget.
- Added 3 flags sets: ImGuiTableFlags (27 flags), ImGuiTableColumnFlags (24 flags), ImGuiTableRowFlags (1 flags).
- Added 5 colors: ImGuiCol_TableHeaderBg, ImGuiCol_TableBorderStrong, ImGuiCol_TableBorderLight, ImGuiCol_TableRowBg, ImGuiCol_TableRowBgAlt.
- Added 1 style var: ImGuiStyleVar_CellPadding.
- Tables: added new Tables Beta API as a replacement for old Columns. (#3740, #2957, #125)
Check out 'Demo->Tables' for many demos.
Read API comments in imgui.h for details. Read extra commentary in imgui_tables.cpp.
- Added 16 functions:
- BeginTable(), EndTable()
- TableNextRow(), TableNextColumn(), TableSetColumnIndex()
- TableSetupColumn(), TableSetupScrollFreeze()
- TableHeadersRow(), TableHeader()
- TableGetRowIndex(), TableGetColumnCount(), TableGetColumnIndex(), TableGetColumnName(), TableGetColumnFlags()
- TableGetSortSpecs(), TableSetBgColor()
- Added 3 flags sets:
- ImGuiTableFlags (29 flags for: features, decorations, sizing policies, padding, clipping, scrolling, sorting etc.)
- ImGuiTableColumnFlags (24 flags for: width policies, default settings, sorting options, indentation options etc.)
- ImGuiTableRowFlags (1 flag for: header row)
- Added 2 structures: ImGuiTableSortSpecs, ImGuiTableColumnSortSpecs
- Added 2 enums: ImGuiSortDirection, ImGuiTableBgTarget
- Added 1 style variable: ImGuiStyleVar_CellPadding
- Added 5 style colors: ImGuiCol_TableHeaderBg, ImGuiCol_TableBorderStrong, ImGuiCol_TableBorderLight, ImGuiCol_TableRowBg, ImGuiCol_TableRowBgAlt.
- Tab Bar: Made it possible to append to an existing tab bar by calling BeginTabBar()/EndTabBar() again.
- Tab Bar: Fixed using more than 128 tabs in a tab bar (scrolling policy recommended).
- Tab Bar: Do not display a tooltip if the name already fits over a given tab. (#3521)
- Tab Bar: Fixed minor/unlikely bug skipping over a button when scrolling left with arrows.
- Tab Bar: Requested ideal content size (for auto-fit) doesn't affect horizontal scrolling. (#3414)
- Drag and Drop: Fix losing drop source ActiveID (and often source tooltip) when opening a TreeNode()
or CollapsingHeader() while dragging. (#1738)
- Drag and Drop: Fix drag and drop to tie same-size drop targets by choosen the later one. Fixes dragging
- Drag and Drop: Fix drag and drop to tie same-size drop targets by chosen the later one. Fixes dragging
into a full-window-sized dockspace inside a zero-padded window. (#3519, #2717) [@Black-Cat]
- Checkbox: Added CheckboxFlags() helper with int* type.
- Checkbox: Added CheckboxFlags() helper with int* type (internals have a template version, not exposed).
- Clipper: Fixed incorrect end-list positioning when using ImGuiListClipper with 1 item (bug in 1.79). (#3663) [@nyorain]
- InputText: Fixed updating cursor/selection position when a callback altered the buffer in a way
where the byte count is unchanged but the decoded character count changes. (#3587) [@gqw]
- InputText: Fixed swiching from single to multi-line while preserving same ID.
- InputText: Fixed switching from single to multi-line while preserving same ID.
- Combo: Fixed using IsItemEdited() after Combo() not matching the return value from Combo(). (#2034)
- DragFloat, DragInt: very slightly increased mouse drag threshold + expressing it as a factor of default value.
- DragFloat, DragInt: added experimental io.ConfigDragClickToInputText feature to enable turning DragXXX widgets
into text input with a simple mouse click-release (without moving). (#3737)
- Nav: Fixed IsItemFocused() from returning false when Nav highlight is hidden because mouse has moved.
It's essentially been always the case but it doesn't make much sense. Instead we will aim at exposing
feedback and control of keyboard/gamepad navigation highlight and mouse hover disable flag. (#787, #2048)
- Metrics: Fixed mishandling of ImDrawCmd::VtxOffset in wireframe mesh renderer.
- Metrics: Rebranded as "Dear ImGui Metrics/Debugger" to clarify its purpose.
- ImDrawList: Added ImDrawList::AddQuadBezierCurve(), ImDrawList::PathQuadBezierCurveTo() quadratic bezier
helpers. (#3127, #3664, #3665) [@aiekick]
- Fonts: Updated GetGlyphRangesJapanese() to include a larger 2999 ideograms selection of Joyo/Jinmeiyo
kanjis, from the previous 1946 ideograms selection. This will consume a some more memory but be generally
much more fitting for Japanese display, until we switch to a more dynamic atlas. (#3627) [@vaiorabbit]
@ -102,25 +203,37 @@ Other Changes:
- Misc: Made EndFrame() assertion for key modifiers being unchanged during the frame (added in 1.76) more
lenient, allowing full mid-frame releases. This is to accommodate the use of mid-frame modal native
windows calls, which leads backends such as GLFW to send key clearing events on focus loss. (#3575)
- Style: Changed default style.WindowRounding value to 0.0f (matches default for multi-viewports).
- Style: Reduced the size of the resizing grip, made alpha less prominent.
- Style: Classic: Increase the default alpha value of WindowBg to be closer to other styles.
- Demo: Clarify usage of right-aligned items in Demo>Layout>Widgets Width.
- Backends: OpenGL3: Use glGetString(GL_VERSION) query instead of glGetIntegerv(GL_MAJOR_VERSION, ...)
when the later returns zero (e.g. Desktop GL 2.x). (#3530) [@xndcn]
- Backends: OpenGL2: Backup and restore GL_SHADE_MODEL and disable GL_NORMAL_ARRAY state to increase
compatibility with legacy code. (#3671)
- Backends: OpenGL3: Backup and restore GL_PRIMITIVE_RESTART state. (#3544) [@Xipiryon]
- Backends: Vulkan: Added support for specifying which subpass to reference during VkPipeline creation. (@3579) [@bdero]
- Backends: OpenGL2, OpenGL3: Backup and restore GL_STENCIL_TEST enable state. (#3668)
- Backends: Vulkan: Added support for specifying which sub-pass to reference during VkPipeline creation. (@3579) [@bdero]
- Backends: DX12: Improve Windows 7 compatibility (for D3D12On7) by loading d3d12.dll dynamically. (#3696) [@Mattiwatti]
- Backends: Win32: Fix setting of io.DisplaySize to invalid/uninitialized data after hwnd has been closed.
- Backends: OSX: Fix keypad-enter key not working on MacOS. (#3554) [@rokups, @lfnoise]
- Examples: Apple+Metal: Consolidated/simplified to get closer to other examples. (#3543) [@warrenm]
- Examples: Apple+Metal: Forward events down so OS key combination like Cmd+Q can work. (#3554) [@rokups]
- Examples: Emscripten: Renamed example_emscripten/ to example_emscripten_opengl3/. (#3632)
- Examples: Emscripten: Added 'make serve' helper to spawn a web-server on localhost. (#3705) [@Horki]
- Examples: DirectX12: Move ImGui::Render() call above the first barrier to clarify its lack of effect on the graphics pipe.
- CI: Fix testing for Windows DLL builds. (#3603, #3601) [@iboB]
- Docs: Split examples/README.txt into docs/BACKENDS.md and docs/EXAMPLES.md improved them.
- Docs: Consistently renamed all occurences of "binding" and "back-end" to "backend" in comments and docs.
- Docs: Improved the wiki and added a https://github.com/ocornut/imgui/wiki/Useful-Widgets page. [@Xipiryon]
- Docs: Split examples/README.txt into docs/BACKENDS.md and docs/EXAMPLES.md, and improved them.
- Docs: Consistently renamed all occurrences of "binding" and "back-end" to "backend" in comments and docs.
-----------------------------------------------------------------------
VERSION 1.79 (Released 2020-10-08)
-----------------------------------------------------------------------
Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.79
Breaking Changes:
- Fonts: Removed ImFont::DisplayOffset in favor of ImFontConfig::GlyphOffset. DisplayOffset was applied
@ -160,7 +273,7 @@ Other Changes:
- InputText: Fixed callback's helper DeleteChars() function when cursor is inside the deleted block. (#3454)
- InputText: Made pressing Down arrow on the last line when it doesn't have a carriage return not move to
the end of the line (so it is consistent with Up arrow, and behave same as Notepad and Visual Studio.
Note that some other text editors instead would move the crusor to the end of the line). [@Xipiryon]
Note that some other text editors instead would move the cursor to the end of the line). [@Xipiryon]
- DragFloat, DragScalar: Fixed ImGuiSliderFlags_ClampOnInput not being honored in the special case
where v_min == v_max. (#3361)
- SliderInt, SliderScalar: Fixed reaching of maximum value with inverted integer min/max ranges, both
@ -188,7 +301,7 @@ Other Changes:
tabs reordered in the tab list popup. [@Xipiryon]
- Columns: Fix inverted ClipRect being passed to renderer when using certain primitives inside of
a fully clipped column. (#3475) [@szreder]
- Popups, Tooltips: Fix edge cases issues with positionning popups and tooltips when they are larger than
- Popups, Tooltips: Fix edge cases issues with positioning popups and tooltips when they are larger than
viewport on either or both axises. [@Rokups]
- Fonts: AddFontDefault() adjust its vertical offset based on floor(size/13) instead of always +1.
Was previously done by altering DisplayOffset.y but wouldn't work for DPI scaled font.
@ -213,6 +326,8 @@ Other Changes:
VERSION 1.78 (Released 2020-08-18)
-----------------------------------------------------------------------
Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.78
Breaking Changes:
- Obsoleted use of the trailing 'float power=1.0f' parameter for those functions: [@Shironekoben, @ocornut]
@ -350,7 +465,7 @@ Other Changes:
- Popups: Added ImGuiPopupFlags_AnyPopupId and ImGuiPopupFlags_AnyPopupLevel flags for IsPopupOpen(),
allowing to check if any popup is open at the current level, if a given popup is open at any popup
level, if any popup is open at all.
- Popups: Fix an edge case where programatically closing a popup while clicking on its empty space
- Popups: Fix an edge case where programmatically closing a popup while clicking on its empty space
would attempt to focus it and close other popups. (#2880)
- Popups: Fix BeginPopupContextVoid() when clicking over the area made unavailable by a modal. (#1636)
- Popups: Clarified some of the comments and function prototypes.
@ -1487,7 +1602,7 @@ Other Changes:
- ImFontAtlas: Added GetGlyphRangesChineseSimplifiedCommon() helper that returns a list of ~2500 most common Simplified Chinese
characters. (#1859) [@JX-Master, @ocornut]
- Examples: OSX: Added imgui_impl_osx.mm backend to be used along with e.g. imgui_impl_opengl2.cpp. (#281, #1870) [@pagghiu, @itamago, @ocornut]
- Examples: GLFW: Made it possible to Shutdown/Init the backend again (by reseting the time storage properly). (#1827) [@ice1000]
- Examples: GLFW: Made it possible to Shutdown/Init the backend again (by resetting the time storage properly). (#1827) [@ice1000]
- Examples: Win32: Fixed handling of mouse wheel messages to support sub-unit scrolling messages (typically sent by track-pads). (#1874) [@zx64]
- Examples: SDL+Vulkan: Added SDL+Vulkan example.
- Examples: Allegro5: Added support for ImGuiConfigFlags_NoMouseCursorChange flag. Added clipboard support.
@ -2262,7 +2377,7 @@ Other Changes:
- Combo(): Right-most button stays highlighted when pop-up is open.
- Combo(): Display pop-up above if there's isn't enough space below / or select largest side. (#505)
- DragFloat(), SliderFloat(), InputFloat(): fixed cases of erroneously returning true repeatedly after a text input modification (e.g. "0.0" --> "0.000" would keep returning true). (#564)
- DragFloat(): Always apply value when mouse is held/widget active, so that an always-reseting variable (e.g. non saved local) can be passed.
- DragFloat(): Always apply value when mouse is held/widget active, so that an always-resetting variable (e.g. non saved local) can be passed.
- InputText(): OS X friendly behaviors: Word movement uses ALT key; Shortcuts uses CMD key; Double-clicking text select a single word; Jumping to next word sets cursor to end of current word instead of beginning of current word. (@zhiayang), (#473)
- InputText(): Added BufTextLen in ImGuiTextEditCallbackData. Requesting user to maintain it if buffer is modified. Zero-ing structure properly before use. (#541)
- CheckboxFlags(): Added support for testing/setting multiple flags at the same time. (@DMartinek) (#555)

View File

@ -98,6 +98,10 @@ Emcripten + SDL2 + OpenGL3+/ES2/ES3 example. <BR>
Note that other examples based on SDL or GLFW + OpenGL could easily be modified to work with Emscripten.
We provide this to make the Emscripten differences obvious, and have them not pollute all other examples.
[example_emscripten_wgpu/](https://github.com/ocornut/imgui/blob/master/examples/example_emscripten_wgpu/) <BR>
Emcripten + GLFW + WebGPU example. <BR>
= main.cpp + imgui_impl_glfw.cpp + imgui_impl_wgpu.cpp
[example_glfw_metal/](https://github.com/ocornut/imgui/blob/master/examples/example_glfw_metal/) <BR>
GLFW (Mac) + Metal example. <BR>
= main.mm + imgui_impl_glfw.cpp + imgui_impl_metal.mm
@ -198,9 +202,9 @@ This is quite long and tedious, because: DirectX12.
**Building**
Unfortunately in 2020 it is still tedious to create and maintain portable build files using external
Unfortunately nowadays it is still tedious to create and maintain portable build files using external
libraries (the kind we're using here to create a window and render 3D triangles) without relying on
third party software. For most examples here we choose to provide:
third party software and build systems. For most examples here we choose to provide:
- Makefiles for Linux/OSX
- Batch files for Visual Studio 2008+
- A .sln project file for Visual Studio 2012+

View File

@ -23,7 +23,7 @@ or view this file with any Markdown viewer.
| [I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around..](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-clipping-or-disappearing-when-i-move-windows-around) |
| [I integrated Dear ImGui in my engine and some elements are displaying outside their expected windows boundaries..](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-displaying-outside-their-expected-windows-boundaries) |
| **Q&A: Usage** |
| **[Why is my widget not reacting when I click on it?<br>How can I have multiple widgets with the same label?<br>Why are multiple widgets reacting when I interact with one?](#q-why-is-my-widget-not-reacting-when-i-click-on-it)** |
| **[Why is my widget not reacting when I click on it?<br>How can I have widgets with an empty label?<br>How can I have multiple widgets with the same label?](#q-why-is-my-widget-not-reacting-when-i-click-on-it)** |
| [How can I display an image? What is ImTextureID, how does it work?](#q-how-can-i-display-an-image-what-is-imtextureid-how-does-it-work)|
| [How can I use my own math types instead of ImVec2/ImVec4?](#q-how-can-i-use-my-own-math-types-instead-of-imvec2imvec4) |
| [How can I interact with standard C++ types (such as std::string and std::vector)?](#q-how-can-i-interact-with-standard-c-types-such-as-stdstring-and-stdvector) |
@ -214,8 +214,6 @@ Button("OK"); // Label = "OK", ID = hash of ("MyOtherWindow", "OK")
End();
```
We used "..." above to signify whatever was already pushed to the ID stack previously:
- If you have a same ID twice in the same location, you'll have a conflict:
```cpp
Button("OK");

View File

@ -70,11 +70,13 @@ If you get an assert stating "Could not load font file!", your font filename is
**Load multiple fonts:**
```cpp
// Init
ImGuiIO& io = ImGui::GetIO();
ImFont* font1 = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels);
ImFont* font2 = io.Fonts->AddFontFromFileTTF("anotherfont.otf", size_pixels);
// Select font at runtime
```
```cpp
// In application loop: select font at runtime
ImGui::Text("Hello"); // use the default font (which is the first loaded font)
ImGui::PushFont(font2);
ImGui::Text("Hello with another font");
@ -145,19 +147,18 @@ ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
**Font Atlas too large?**
- If you have very large number of glyphs or multiple fonts, the texture may become too big for your graphics API. The typical result of failing to upload a texture is if every glyphs appears as white rectangles.
- In particular, using a large range such as `GetGlyphRangesChineseSimplifiedCommon()` is not recommended unless you set `OversampleH`/`OversampleV` to 1 and use a small font size.
- Mind the fact that some graphics drivers have texture size limitation.
- If you are building a PC application, mind the fact that your users may use hardware with lower limitations than yours.
- Mind the fact that some graphics drivers have texture size limitation. If you are building a PC application, mind the fact that your users may use hardware with lower limitations than yours.
Some solutions:
1. Reduce glyphs ranges by calculating them from source localization data.
You can use the `ImFontGlyphRangesBuilder` for this purpose, this will be the biggest win!
2. You may reduce oversampling, e.g. `font_config.OversampleH = font_config.OversampleV = 1`, this will largely reduce your texture size.
You can use the `ImFontGlyphRangesBuilder` for this purpose and rebuilding your atlas between frames when new characters are needed. This will be the biggest win!
2. You may reduce oversampling, e.g. `font_config.OversampleH = 2`, this will largely reduce your texture size.
Note that while OversampleH = 2 looks visibly very close to 3 in most situations, with OversampleH = 1 the quality drop will be noticeable.
3. Set `io.Fonts.TexDesiredWidth` to specify a texture width to minimize texture height (see comment in `ImFontAtlas::Build()` function).
4. Set `io.Fonts.Flags |= ImFontAtlasFlags_NoPowerOfTwoHeight;` to disable rounding the texture height to the next power of two.
5. Read about oversampling [here](https://github.com/nothings/stb/blob/master/tests/oversample).
6. To support the extended range of unicode beyond 0xFFFF (e.g. emoticons, dingbats, symbols, shapes, ancient languages, etc...) add `#define IMGUI_USE_WCHAR32`in your `imconfig.h`
6. To support the extended range of unicode beyond 0xFFFF (e.g. emoticons, dingbats, symbols, shapes, ancient languages, etc...) add `#define IMGUI_USE_WCHAR32`in your `imconfig.h`.
##### [Return to Index](#index)

View File

@ -20,7 +20,7 @@ Dear ImGui is designed to **enable fast iterations** and to **empower programmer
Dear ImGui is particularly suited to integration in games engine (for tooling), real-time 3D applications, fullscreen applications, embedded applications, or any applications on consoles platforms where operating system features are non-standard.
| [Usage](#usage) - [How it works](#how-it-works) - [Releases](#releases) - [Demo](#demo) - [Integration](#integration) |
| [Usage](#usage) - [How it works](#how-it-works) - [Releases & Changelogs](#releases--changelogs) - [Demo](#demo) - [Integration](#integration) |
:----------------------------------------------------------: |
| [Upcoming changes](#upcoming-changes) - [Gallery](#gallery) - [Support, FAQ](#support-frequently-asked-questions-faq) - [How to help](#how-to-help) - [Sponsors](#sponsors) - [Credits](#credits) - [License](#license) |
| [Wiki](https://github.com/ocornut/imgui/wiki) - [Languages & frameworks backends/bindings](https://github.com/ocornut/imgui/wiki/Bindings) - [Software using Dear ImGui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) - [User quotes](https://github.com/ocornut/imgui/wiki/Quotes) |
@ -93,9 +93,10 @@ Dear ImGui outputs vertex buffers and command lists that you can easily render i
_A common misunderstanding is to mistake immediate mode gui for immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes as the gui functions are called. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
### Releases
### Releases & Changelogs
See [Releases](https://github.com/ocornut/imgui/releases) page.
Reading the changelogs is a good way to keep up to date with the things Dear ImGui has to offer, and maybe will give you ideas of some features that you've been ignoring until now!
### Demo
@ -115,13 +116,13 @@ On most platforms and when using C++, **you should be able to use a combination
Integrating Dear ImGui within your custom engine is a matter of 1) wiring mouse/keyboard/gamepad inputs 2) uploading one texture to your GPU/render engine 3) providing a render function that can bind textures and render textured triangles. The [examples/](https://github.com/ocornut/imgui/tree/master/examples) folder is populated with applications doing just that. If you are an experienced programmer at ease with those concepts, it should take you less than two hours to integrate Dear ImGui in your custom engine. **Make sure to spend time reading the [FAQ](https://www.dearimgui.org/faq), comments, and some of the examples/ application!**
Officially maintained backends/bindings (in repository):
- Renderers: DirectX9, DirectX10, DirectX11, DirectX12, OpenGL (legacy), OpenGL3/ES/ES2 (modern), Vulkan, Metal.
- Renderers: DirectX9, DirectX10, DirectX11, DirectX12, Metal, OpenGL (legacy), OpenGL3/ES/ES2 (modern), Vulkan, WebGPU.
- Platforms: GLFW, SDL2, Win32, Glut, OSX.
- Frameworks: Emscripten, Allegro5, Marmalade.
[Third-party backends/bindings](https://github.com/ocornut/imgui/wiki/Bindings) wiki page:
- Languages: C, C# and: Beef, ChaiScript, Crystal, D, Go, Haskell, Haxe/hxcpp, Java, JavaScript, Julia, Kotlin, Lua, Odin, Pascal, PureBasic, Python, Ruby, Rust, Swift...
- Frameworks: AGS/Adventure Game Studio, Amethyst, bsf, Cinder, Cocos2d-x, Diligent Engine, Flexium, GML/Game Maker Studio2, Godot, GTK3+OpenGL3, Irrlicht Engine, LÖVE+LUA, Magnum, NanoRT, nCine, Nim Game Lib, Ogre, openFrameworks, OSG/OpenSceneGraph, Orx, Photoshop, px_render, Qt/QtDirect3D, SFML, Sokol, Unity, Unreal Engine 4, vtk, Win32 GDI, WxWidgets.
- Languages: C, C# and: Beef, ChaiScript, Crystal, D, Go, Haskell, Haxe/hxcpp, Java, JavaScript, Julia, Kotlin, Lobster, Lua, Odin, Pascal, PureBasic, Python, Ruby, Rust, Swift...
- Frameworks: AGS/Adventure Game Studio, Amethyst, Blender, bsf, Cinder, Cocos2d-x, Diligent Engine, Flexium, GML/Game Maker Studio2, GLEQ, Godot, GTK3+OpenGL3, Irrlicht Engine, LÖVE+LUA, Magnum, Monogame, NanoRT, nCine, Nim Game Lib, Nintendo 3DS & Switch (homebrew), Ogre, openFrameworks, OSG/OpenSceneGraph, Orx, Photoshop, px_render, Qt/QtDirect3D, SDL_Renderer, SFML, Sokol, Unity, Unreal Engine 4, vtk, VulkanHpp, VulkanSceneGraph, Win32 GDI, WxWidgets.
- Note that C bindings ([cimgui](https://github.com/cimgui/cimgui)) are auto-generated, you can use its json/lua output to generate bindings for other languages.
[Useful widgets and extensions](https://github.com/ocornut/imgui/wiki/Useful-Widgets) wiki page:
@ -131,8 +132,7 @@ Also see [Wiki](https://github.com/ocornut/imgui/wiki) for more links and ideas.
### Upcoming Changes
Some of the goals for 2020 are:
- Work on new Tables API (to replace Columns). (see [#2957](https://github.com/ocornut/imgui/issues/2957), in public [tables](https://github.com/ocornut/imgui/tree/tables) branch looking for feedback)
Some of the goals for 2021 are:
- Work on Docking (see [#2109](https://github.com/ocornut/imgui/issues/2109), in public [docking](https://github.com/ocornut/imgui/tree/docking) branch)
- Work on Multi-Viewport / Multiple OS windows. (see [#1542](https://github.com/ocornut/imgui/issues/1542), in public [docking](https://github.com/ocornut/imgui/tree/docking) branch looking for feedback)
- Work on gamepad/keyboard controls. (see [#787](https://github.com/ocornut/imgui/issues/787))
@ -151,7 +151,7 @@ Custom engine
Custom engine
[![screenshot tool](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v160/editor_white_preview.jpg)](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v160/editor_white.png)
[Tracy Profiler](https://bitbucket.org/wolfpld/tracy)
[Tracy Profiler](https://github.com/wolfpld/tracy)
![tracy profiler](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v176/tracy_profiler.png)
### Support, Frequently Asked Questions (FAQ)
@ -195,15 +195,16 @@ See [Sponsors](https://github.com/ocornut/imgui/wiki/Sponsors) page.
Sponsors
--------
Ongoing Dear ImGui development is financially supported by users and private sponsors, recently:
Ongoing Dear ImGui development is currently financially supported by users and private sponsors:
*Platinum-chocolate sponsors*
- [Blizzard](https://careers.blizzard.com/en-us/openings/engineering/all/all/all/1), [Google](https://github.com/google/filament), [Nvidia](https://developer.nvidia.com/nvidia-omniverse), [Ubisoft](https://montreal.ubisoft.com/en/ubisoft-sponsors-user-interface-library-for-c-dear-imgui/)
*Double-chocolate and Salty caramel sponsors*
- [Activision](https://careers.activision.com/c/programmingsoftware-engineering-jobs), [Arkane Studios](https://www.arkane-studios.com), [Dotemu](http://www.dotemu.com), [Framefield](http://framefield.com), [Grinding Gear Games](https://www.grindinggear.com), [Hexagon](https://hexagonxalt.com/the-technology/xalt-visualization), [Kylotonn](https://www.kylotonn.com), [Media Molecule](http://www.mediamolecule.com), [Mesh Consultants](https://www.meshconsultants.ca), [Mobigame](http://www.mobigame.net), [Nadeo](https://www.nadeo.com), [Next Level Games](https://www.nextlevelgames.com), [RAD Game Tools](http://www.radgametools.com/), [Supercell](http://www.supercell.com), [Remedy Entertainment](https://www.remedygames.com/), [Unit 2 Games](https://unit2games.com/)
- [Activision](https://careers.activision.com/c/programmingsoftware-engineering-jobs), [Aras Pranckevičius](https://aras-p.info), [Arkane Studios](https://www.arkane-studios.com), [Framefield](http://framefield.com), [Grinding Gear Games](https://www.grindinggear.com), [Kylotonn](https://www.kylotonn.com), [Next Level Games](https://www.nextlevelgames.com), [RAD Game Tools](http://www.radgametools.com/), [Supercell](http://www.supercell.com)
From November 2014 to December 2019, ongoing development has also been financially supported by its users on Patreon and through individual donations. Please see [detailed list of Dear ImGui supporters](https://github.com/ocornut/imgui/wiki/Sponsors).
Please see [detailed list of Dear ImGui supporters](https://github.com/ocornut/imgui/wiki/Sponsors) for past sponsors.
From November 2014 to December 2019, ongoing development has also been financially supported by its users on Patreon and through individual donations.
**THANK YOU to all past and present supporters for helping to keep this project alive and thriving!**

View File

@ -129,18 +129,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- group: IsHovered() after EndGroup() covers whole aabb rather than the intersection of individual items. Is that desirable?
- group: merge deactivation/activation within same group (fwd WasEdited flag). (#2550)
- columns: sizing policy (e.g. for each column: fixed size, %, fill, distribute default size among fills) (#513, #125)
- columns: add a conditional parameter to SetColumnOffset() (#513, #125)
- columns: headers. re-orderable. (#513, #125)
- columns: optional sorting modifiers (up/down), sort list so sorting can be done multi-criteria. notify user when sort order changed.
- columns: option to alternate background colors on odd/even scanlines.
- columns: allow columns to recurse.
- columns: allow a same columns set to be interrupted by e.g. CollapsingHeader and resume with columns in sync when moving them.
- columns: sizing is lossy when columns width is very small (default width may turn negative etc.)
- columns: separator function or parameter that works within the column (currently Separator() bypass all columns) (#125)
- columns: flag to add horizontal separator above/below)
- columns/layout: setup minimum line height (equivalent of automatically calling AlignFirstTextHeightToWidgets)
!- color: the color conversion helpers/types are a mess and needs sorting out.
- color: (api breaking) ImGui::ColorConvertXXX functions should be loose ImColorConvertXX to match imgui_internals.h
@ -197,12 +185,11 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- combo: flag for BeginCombo to not return true when unchanged (#1182)
- combo: a way/helper to customize the combo preview (#1658)
- combo/listbox: keyboard control. need InputText-like non-active focus + key handling. considering keyboard for custom listbox (pr #203)
- listbox: refactor and clean the begin/end api
- listbox: multiple selection.
- listbox: unselect option (#1208)
- listbox: make it easier/more natural to implement range-select (need some sort of info/ref about the last clicked/focused item that user can translate to an index?) (wip stash)
- listbox: user may want to initial scroll to focus on the one selected value?
- listbox: expose hovered item for a basic ListBox
- listbox: expose hovered item for a simplified ListBox api
- listbox: keyboard navigation.
- listbox: disable capturing mouse wheel if the listbox has no scrolling. (#1681)
- listbox: scrolling should track modified selection.
@ -259,12 +246,14 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- style: gradients fill (#1223) ~ 2 bg colors for each fill? tricky with rounded shapes and using textures for corners.
- style editor: color child window height expressed in multiple of line height.
- log: improve logging of ArrowButton, ListBox, TabItem
- log: carry on indent / tree depth when opening a child window
- log: enabling log ends up pushing and growing vertices buffers because we don't distinguish layout vs render clipping
- log: have more control over the log scope (e.g. stop logging when leaving current tree node scope)
- log: be able to log anything (e.g. right-click on a window/tree-node, shows context menu? log into tty/file/clipboard)
- log: let user copy any window content to clipboard easily (CTRL+C on windows? while moving it? context menu?). code is commented because it fails with multiple Begin/End pairs.
- log: obsolete LogButtons() all together.
- log: LogButtons() options for specifying depth and/or hiding depth slider
- log: enabling log ends up pushing and growing vertices buffersbecause we don't distinguish layout vs render clipping
- filters: set a current filter that tree node can automatically query to hide themselves
- filters: handle wild-cards (with implicit leading/trailing *), reg-exprs

View File

@ -7,15 +7,16 @@
# (On Windows, you may need to execute emsdk_env.bat or encmdprompt.bat ahead)
#
# Running `make` will produce three files:
# - example_emscripten_opengl3.html
# - example_emscripten_opengl3.js
# - example_emscripten_opengl3.wasm
# - web/index.html
# - web/index.js
# - web/index.wasm
#
# All three are needed to run the demo.
CC = emcc
CXX = em++
EXE = example_emscripten_opengl3.html
WEB_DIR = web
EXE = $(WEB_DIR)/index.html
IMGUI_DIR = ../..
SOURCES = main.cpp
SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp
@ -78,8 +79,14 @@ LDFLAGS += --shell-file shell_minimal.html
all: $(EXE)
@echo Build complete for $(EXE)
$(EXE): $(OBJS)
$(CXX) -o $@ $^ $(LIBS) $(LDFLAGS)
$(WEB_DIR):
mkdir $@
serve: all
python3 -m http.server -d $(WEB_DIR)
$(EXE): $(OBJS) $(WEB_DIR)
$(CXX) -o $@ $(OBJS) $(LIBS) $(LDFLAGS)
clean:
rm -f $(EXE) $(OBJS) *.js *.wasm *.wasm.pre
rm -rf $(OBJS) $(WEB_DIR)

View File

@ -1,4 +1,3 @@
## How to Build
- You need to install Emscripten from https://emscripten.org/docs/getting_started/downloads.html, and have the environment variables set, as described in https://emscripten.org/docs/getting_started/downloads.html#installation-instructions
@ -9,10 +8,13 @@
## How to Run
To run on a local machine:
- Generally you may need a local webserver. Quoting [https://emscripten.org/docs/getting_started](https://emscripten.org/docs/getting_started/Tutorial.html#generating-html):<br>
- `make serve` will use Python3 to spawn a local webserver, you can then browse http://localhost:8000 to access your build.
- Otherwise, generally you will need a local webserver:
- Quoting [https://emscripten.org/docs/getting_started](https://emscripten.org/docs/getting_started/Tutorial.html#generating-html):<br>
_"Unfortunately several browsers (including Chrome, Safari, and Internet Explorer) do not support file:// [XHR](https://emscripten.org/docs/site/glossary.html#term-xhr) requests, and cant load extra files needed by the HTML (like a .wasm file, or packaged file data as mentioned lower down). For these browsers youll need to serve the files using a [local webserver](https://emscripten.org/docs/getting_started/FAQ.html#faq-local-webserver) and then open http://localhost:8000/hello.html."_
- Emscripten SDK has a handy `emrun` command: `emrun example_emscripten_opengl3.html` which will spawn a temporary local webserver. See https://emscripten.org/docs/compiling/Running-html-files-with-emrun.html for details.
- Otherwise you may use Python builtin webserver: `python -m http.server` in Python 3 or `python -m SimpleHTTPServer` in Python 2. After doing that, you can visit http://localhost:8000/.
- Emscripten SDK has a handy `emrun` command: `emrun web/example_emscripten_opengl3.html --browser firefox` which will spawn a temporary local webserver (in Firefox). See https://emscripten.org/docs/compiling/Running-html-files-with-emrun.html for details.
- You may use Python 3 builtin webserver: `python -m http.server -d web` (this is what `make serve` uses).
- You may use Python 2 builtin webserver: `cd web && python -m SimpleHTTPServer`.
## Obsolete features:

View File

@ -21,7 +21,7 @@ SDL_Window* g_Window = NULL;
SDL_GLContext g_GLContext = NULL;
// For clarity, our main loop code is declared at the end.
void main_loop(void*);
static void main_loop(void*);
int main(int, char**)
{
@ -99,7 +99,7 @@ int main(int, char**)
emscripten_set_main_loop_arg(main_loop, NULL, 0, true);
}
void main_loop(void* arg)
static void main_loop(void* arg)
{
ImGuiIO& io = ImGui::GetIO();
IM_UNUSED(arg); // We can pass this argument as the second parameter of emscripten_set_main_loop_arg(), but we don't use that.

View File

@ -0,0 +1,85 @@
#
# Makefile to use with emscripten
# See https://emscripten.org/docs/getting_started/downloads.html
# for installation instructions.
#
# This Makefile assumes you have loaded emscripten's environment.
# (On Windows, you may need to execute emsdk_env.bat or encmdprompt.bat ahead)
#
# Running `make` will produce three files:
# - web/index.html (current stored in the repository)
# - web/index.js
# - web/index.wasm
#
# All three are needed to run the demo.
CC = emcc
CXX = em++
WEB_DIR = web
EXE = $(WEB_DIR)/index.js
IMGUI_DIR = ../..
SOURCES = main.cpp
SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp
SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui_impl_wgpu.cpp
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
UNAME_S := $(shell uname -s)
##---------------------------------------------------------------------
## EMSCRIPTEN OPTIONS
##---------------------------------------------------------------------
EMS += -s USE_GLFW=3 -s USE_WEBGPU=1 -s WASM=1
EMS += -s ALLOW_MEMORY_GROWTH=1
EMS += -s DISABLE_EXCEPTION_CATCHING=1 -s NO_EXIT_RUNTIME=0
EMS += -s ASSERTIONS=1
# Emscripten allows preloading a file or folder to be accessible at runtime.
# The Makefile for this example project suggests embedding the misc/fonts/ folder into our application, it will then be accessible as "/fonts"
# See documentation for more details: https://emscripten.org/docs/porting/files/packaging_files.html
# (Default value is 0. Set to 1 to enable file-system and include the misc/fonts/ folder as part of the build.)
USE_FILE_SYSTEM ?= 0
ifeq ($(USE_FILE_SYSTEM), 0)
EMS += -s NO_FILESYSTEM=1 -DIMGUI_DISABLE_FILE_FUNCTIONS
endif
ifeq ($(USE_FILE_SYSTEM), 1)
LDFLAGS += --no-heap-copy --preload-file ../../misc/fonts@/fonts
endif
##---------------------------------------------------------------------
## FINAL BUILD FLAGS
##---------------------------------------------------------------------
CPPFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
#CPPFLAGS += -g
CPPFLAGS += -Wall -Wformat -Os
CPPFLAGS += $(EMS)
LIBS += $(EMS)
#LDFLAGS += --shell-file shell_minimal.html
##---------------------------------------------------------------------
## BUILD RULES
##---------------------------------------------------------------------
%.o:%.cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<
%.o:$(IMGUI_DIR)/%.cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<
%.o:$(IMGUI_DIR)/backends/%.cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<
all: $(EXE)
@echo Build complete for $(EXE)
$(WEB_DIR):
mkdir $@
serve: all
python3 -m http.server -d $(WEB_DIR)
$(EXE): $(OBJS) $(WEB_DIR)
$(CXX) -o $@ $(OBJS) $(LIBS) $(LDFLAGS)
clean:
rm -f $(EXE) $(OBJS) $(WEB_DIR)/*.js $(WEB_DIR)/*.wasm $(WEB_DIR)/*.wasm.pre

View File

@ -0,0 +1,10 @@
# How to Build
- You need to install Emscripten from https://emscripten.org/docs/getting_started/downloads.html, and have the environment variables set, as described in https://emscripten.org/docs/getting_started/downloads.html#installation-instructions
- Depending on your configuration, in Windows you may need to run `emsdk/emsdk_env.bat` in your console to access the Emscripten command-line tools.
- Then build using `make` while in the `example_emscripten_wgpu/` directory.
- Requires Emscripten 2.0.10 (December 2020) due to GLFW adaptations

View File

@ -0,0 +1,245 @@
// Dear ImGui: standalone example application for Emscripten, using GLFW + WebGPU
// (Emscripten is a C++-to-javascript compiler, used to publish executables for the web. See https://emscripten.org/)
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Read online: https://github.com/ocornut/imgui/tree/master/docs
#include "imgui.h"
#include "imgui_impl_glfw.h"
#include "imgui_impl_wgpu.h"
#include <stdio.h>
#include <emscripten.h>
#include <emscripten/html5.h>
#include <emscripten/html5_webgpu.h>
#include <GLFW/glfw3.h>
#include <webgpu/webgpu.h>
#include <webgpu/webgpu_cpp.h>
// Global WebGPU required states
static WGPUDevice wgpu_device = NULL;
static WGPUSurface wgpu_surface = NULL;
static WGPUSwapChain wgpu_swap_chain = NULL;
static int wgpu_swap_chain_width = 0;
static int wgpu_swap_chain_height = 0;
// States tracked across render frames
static bool show_demo_window = true;
static bool show_another_window = false;
static ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
// Forward declarations
static bool init_wgpu();
static void main_loop(void* window);
static void print_glfw_error(int error, const char* description);
static void print_wgpu_error(WGPUErrorType error_type, const char* message, void*);
int main(int, char**)
{
glfwSetErrorCallback(print_glfw_error);
if (!glfwInit())
return 1;
// Make sure GLFW does not initialize any graphics context.
// This needs to be done explicitly later
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
GLFWwindow* window = glfwCreateWindow(1280, 720, "Dear ImGui GLFW+WebGPU example", NULL, NULL);
if (!window)
{
glfwTerminate();
return 1;
}
// Initialize the WebGPU environment
if (!init_wgpu())
{
if (window)
glfwDestroyWindow(window);
glfwTerminate();
return 1;
}
glfwShowWindow(window);
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
// For an Emscripten build we are disabling file-system access, so let's not attempt to do a fopen() of the imgui.ini file.
// You may manually call LoadIniSettingsFromMemory() to load settings from your own storage.
io.IniFilename = NULL;
// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Setup Platform/Renderer backends
ImGui_ImplGlfw_InitForOther(window, true);
ImGui_ImplWGPU_Init(wgpu_device, 3, WGPUTextureFormat_RGBA8Unorm);
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
// - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
// - Read 'docs/FONTS.md' for more instructions and details.
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
// - Emscripten allows preloading a file or folder to be accessible at runtime. See Makefile for details.
//io.Fonts->AddFontDefault();
#ifndef IMGUI_DISABLE_FILE_FUNCTIONS
io.Fonts->AddFontFromFileTTF("fonts/Roboto-Medium.ttf", 16.0f);
//io.Fonts->AddFontFromFileTTF("fonts/Cousine-Regular.ttf", 15.0f);
//io.Fonts->AddFontFromFileTTF("fonts/DroidSans.ttf", 16.0f);
//io.Fonts->AddFontFromFileTTF("fonts/ProggyTiny.ttf", 10.0f);
//ImFont* font = io.Fonts->AddFontFromFileTTF("fonts/ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese());
//IM_ASSERT(font != NULL);
#endif
// This function will directly return and exit the main function.
// Make sure that no required objects get cleaned up.
// This way we can use the browsers 'requestAnimationFrame' to control the rendering.
emscripten_set_main_loop_arg(main_loop, window, 0, false);
return 0;
}
static bool init_wgpu()
{
wgpu_device = emscripten_webgpu_get_device();
if (!wgpu_device)
return false;
wgpuDeviceSetUncapturedErrorCallback(wgpu_device, print_wgpu_error, NULL);
// Use C++ wrapper due to misbehavior in Emscripten.
// Some offset computation for wgpuInstanceCreateSurface in JavaScript
// seem to be inline with struct alignments in the C++ structure
wgpu::SurfaceDescriptorFromCanvasHTMLSelector html_surface_desc = {};
html_surface_desc.selector = "#canvas";
wgpu::SurfaceDescriptor surface_desc = {};
surface_desc.nextInChain = &html_surface_desc;
// Use 'null' instance
wgpu::Instance instance = {};
wgpu_surface = instance.CreateSurface(&surface_desc).Release();
return true;
}
static void main_loop(void* window)
{
glfwPollEvents();
int width, height;
glfwGetFramebufferSize((GLFWwindow*) window, &width, &height);
// React to changes in screen size
if (width != wgpu_swap_chain_width && height != wgpu_swap_chain_height)
{
ImGui_ImplWGPU_InvalidateDeviceObjects();
if (wgpu_swap_chain)
wgpuSwapChainRelease(wgpu_swap_chain);
wgpu_swap_chain_width = width;
wgpu_swap_chain_height = height;
WGPUSwapChainDescriptor swap_chain_desc = {};
swap_chain_desc.usage = WGPUTextureUsage_OutputAttachment;
swap_chain_desc.format = WGPUTextureFormat_RGBA8Unorm;
swap_chain_desc.width = width;
swap_chain_desc.height = height;
swap_chain_desc.presentMode = WGPUPresentMode_Fifo;
wgpu_swap_chain = wgpuDeviceCreateSwapChain(wgpu_device, wgpu_surface, &swap_chain_desc);
ImGui_ImplWGPU_CreateDeviceObjects();
}
// Start the Dear ImGui frame
ImGui_ImplWGPU_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
// 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!).
if (show_demo_window)
ImGui::ShowDemoWindow(&show_demo_window);
// 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window.
{
static float f = 0.0f;
static int counter = 0;
ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it.
ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too)
ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state
ImGui::Checkbox("Another Window", &show_another_window);
ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated)
counter++;
ImGui::SameLine();
ImGui::Text("counter = %d", counter);
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
ImGui::End();
}
// 3. Show another simple window.
if (show_another_window)
{
ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
ImGui::Text("Hello from another window!");
if (ImGui::Button("Close Me"))
show_another_window = false;
ImGui::End();
}
// Rendering
ImGui::Render();
WGPURenderPassColorAttachmentDescriptor color_attachments = {};
color_attachments.loadOp = WGPULoadOp_Clear;
color_attachments.storeOp = WGPUStoreOp_Store;
color_attachments.clearColor = { clear_color.x, clear_color.y, clear_color.z, clear_color.w };
color_attachments.attachment = wgpuSwapChainGetCurrentTextureView(wgpu_swap_chain);
WGPURenderPassDescriptor render_pass_desc = {};
render_pass_desc.colorAttachmentCount = 1;
render_pass_desc.colorAttachments = &color_attachments;
render_pass_desc.depthStencilAttachment = NULL;
WGPUCommandEncoderDescriptor enc_desc = {};
WGPUCommandEncoder encoder = wgpuDeviceCreateCommandEncoder(wgpu_device, &enc_desc);
WGPURenderPassEncoder pass = wgpuCommandEncoderBeginRenderPass(encoder, &render_pass_desc);
ImGui_ImplWGPU_RenderDrawData(ImGui::GetDrawData(), pass);
wgpuRenderPassEncoderEndPass(pass);
WGPUCommandBufferDescriptor cmd_buffer_desc = {};
WGPUCommandBuffer cmd_buffer = wgpuCommandEncoderFinish(encoder, &cmd_buffer_desc);
WGPUQueue queue = wgpuDeviceGetDefaultQueue(wgpu_device);
wgpuQueueSubmit(queue, 1, &cmd_buffer);
}
static void print_glfw_error(int error, const char* description)
{
printf("Glfw Error %d: %s\n", error, description);
}
static void print_wgpu_error(WGPUErrorType error_type, const char* message, void*)
{
const char* error_type_lbl = "";
switch (error_type)
{
case WGPUErrorType_Validation: error_type_lbl = "Validation"; break;
case WGPUErrorType_OutOfMemory: error_type_lbl = "Out of memory"; break;
case WGPUErrorType_Unknown: error_type_lbl = "Unknown"; break;
case WGPUErrorType_DeviceLost: error_type_lbl = "Device lost"; break;
default: error_type_lbl = "Unknown";
}
printf("%s error: %s\n", error_type_lbl, message);
}

View File

@ -0,0 +1,80 @@
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"/>
<title>Dear ImGui Emscripten+WebGPU example</title>
<style>
body { margin: 0; background-color: black }
.emscripten {
position: absolute;
top: 0px;
left: 0px;
margin: 0px;
border: 0;
width: 100%;
height: 100%;
overflow: hidden;
display: block;
image-rendering: optimizeSpeed;
image-rendering: -moz-crisp-edges;
image-rendering: -o-crisp-edges;
image-rendering: -webkit-optimize-contrast;
image-rendering: optimize-contrast;
image-rendering: crisp-edges;
image-rendering: pixelated;
-ms-interpolation-mode: nearest-neighbor;
}
</style>
</head>
<body>
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas>
<script type='text/javascript'>
var Module;
(async () => {
Module = {
preRun: [],
postRun: [],
print: (function() {
return function(text) {
text = Array.prototype.slice.call(arguments).join(' ');
console.log(text);
};
})(),
printErr: function(text) {
text = Array.prototype.slice.call(arguments).join(' ');
console.error(text);
},
canvas: (function() {
var canvas = document.getElementById('canvas');
//canvas.addEventListener("webglcontextlost", function(e) { alert('FIXME: WebGL context lost, please reload the page'); e.preventDefault(); }, false);
return canvas;
})(),
setStatus: function(text) {
console.log("status: " + text);
},
monitorRunDependencies: function(left) {
// no run dependencies to log
}
};
window.onerror = function() {
console.log("onerror: " + event);
};
// Initialize the graphics adapter
{
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
Module.preinitializedWebGPUDevice = device;
}
{
const js = document.createElement('script');
js.async = true;
js.src = "index.js";
document.body.appendChild(js);
}
})();
</script>
</body>
</html>

View File

@ -1,3 +1,8 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
mkdir Debug
cl /nologo /Zi /MD /I .. /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\backends\imgui_impl_opengl2.cpp ..\..\backends\imgui_impl_glfw.cpp ..\..\imgui*.cpp /FeDebug/example_glfw_opengl2.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib
@set OUT_DIR=Debug
@set OUT_EXE=example_glfw_opengl2
@set INCLUDES=/I..\.. /I..\..\backends /I..\libs\glfw\include
@set SOURCES=main.cpp ..\..\backends\imgui_impl_opengl2.cpp ..\..\backends\imgui_impl_glfw.cpp ..\..\imgui*.cpp
@set LIBS=/LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib
mkdir %OUT_DIR%
cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%

View File

@ -136,7 +136,7 @@ int main(int, char**)
glClear(GL_COLOR_BUFFER_BIT);
// If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!),
// you may need to backup/reset/restore current shader using the commented lines below.
// you may need to backup/reset/restore other state, e.g. for current shader using the commented lines below.
//GLint last_program;
//glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
//glUseProgram(0);

View File

@ -1,3 +1,8 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
mkdir Debug
cl /nologo /Zi /MD /I .. /I ..\.. /I ..\libs\glfw\include /I ..\libs\gl3w *.cpp ..\..\backends\imgui_impl_glfw.cpp ..\..\backends\imgui_impl_opengl3.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c /FeDebug/example_glfw_opengl3.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib
@set OUT_DIR=Debug
@set OUT_EXE=example_glfw_opengl3
@set INCLUDES=/I..\.. /I..\..\backends /I..\libs\glfw\include /I..\libs\gl3w
@set SOURCES=main.cpp ..\..\backends\imgui_impl_glfw.cpp ..\..\backends\imgui_impl_opengl3.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c
@set LIBS=/LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib
mkdir %OUT_DIR%
cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%

View File

@ -1,7 +1,14 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
mkdir Debug
cl /nologo /Zi /MD /I .. /I ..\.. /I ..\libs\glfw\include /I %VULKAN_SDK%\include *.cpp ..\..\backends\imgui_impl_vulkan.cpp ..\..\backends\imgui_impl_glfw.cpp ..\..\imgui*.cpp /FeDebug/example_glfw_vulkan.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 /libpath:%VULKAN_SDK%\lib32 glfw3.lib opengl32.lib gdi32.lib shell32.lib vulkan-1.lib
@set OUT_EXE=example_glfw_vulkan
@set INCLUDES=/I..\.. /I..\..\backends /I..\libs\glfw\include /I %VULKAN_SDK%\include
@set SOURCES=main.cpp ..\..\backends\imgui_impl_vulkan.cpp ..\..\backends\imgui_impl_glfw.cpp ..\..\imgui*.cpp
@set LIBS=/LIBPATH:..\libs\glfw\lib-vc2010-32 /libpath:%VULKAN_SDK%\lib32 glfw3.lib opengl32.lib gdi32.lib shell32.lib vulkan-1.lib
mkdir Release
cl /nologo /Zi /MD /Ox /Oi /I .. /I ..\.. /I ..\libs\glfw\include /I %VULKAN_SDK%\include *.cpp ..\..\backends\imgui_impl_vulkan.cpp ..\..\backends\imgui_impl_glfw.cpp ..\..\imgui*.cpp /FeRelease/example_glfw_vulkan.exe /FoRelease/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 /libpath:%VULKAN_SDK%\lib32 glfw3.lib opengl32.lib gdi32.lib shell32.lib vulkan-1.lib
@set OUT_DIR=Debug
mkdir %OUT_DIR%
cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
@set OUT_DIR=Release
mkdir %OUT_DIR%
cl /nologo /Zi /MD /Ox /Oi %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%

View File

@ -1,7 +1,13 @@
@REM Build for Visual Studio compiler. Run your copy of amd64/vcvars32.bat to setup 64-bit command-line compiler.
mkdir Debug
cl /nologo /Zi /MD /I .. /I ..\.. /I ..\libs\glfw\include /I %VULKAN_SDK%\include *.cpp ..\..\backends\imgui_impl_vulkan.cpp ..\..\backends\imgui_impl_glfw.cpp ..\..\imgui*.cpp /FeDebug/example_glfw_vulkan.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-64 /libpath:%VULKAN_SDK%\lib glfw3.lib opengl32.lib gdi32.lib shell32.lib vulkan-1.lib
@set INCLUDES=/I..\.. /I..\..\backends /I..\libs\glfw\include /I %VULKAN_SDK%\include
@set SOURCES=main.cpp ..\..\backends\imgui_impl_vulkan.cpp ..\..\backends\imgui_impl_glfw.cpp ..\..\imgui*.cpp
@set LIBS=/LIBPATH:..\libs\glfw\lib-vc2010-64 /libpath:%VULKAN_SDK%\lib glfw3.lib opengl32.lib gdi32.lib shell32.lib vulkan-1.lib
mkdir Release
cl /nologo /Zi /MD /Ox /Oi /I .. /I ..\.. /I ..\libs\glfw\include /I %VULKAN_SDK%\include *.cpp ..\..\backends\imgui_impl_vulkan.cpp ..\..\backends\imgui_impl_glfw.cpp ..\..\imgui*.cpp /FeRelease/example_glfw_vulkan.exe /FoRelease/ /link /LIBPATH:..\libs\glfw\lib-vc2010-64 /libpath:%VULKAN_SDK%\lib glfw3.lib opengl32.lib gdi32.lib shell32.lib vulkan-1.lib
@set OUT_DIR=Debug
mkdir %OUT_DIR%
cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
@set OUT_DIR=Release
mkdir %OUT_DIR%
cl /nologo /Zi /MD /Ox /Oi %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%

View File

@ -2,8 +2,8 @@
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Read online: https://github.com/ocornut/imgui/tree/master/docs
// !!! GLUT/FreeGLUT IS OBSOLETE SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!!
// !!! If someone or something is teaching you GLUT in 2020, you are being abused. Please show some resistance. !!!
// !!! GLUT/FreeGLUT IS OBSOLETE PREHISTORIC SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!!
// !!! If someone or something is teaching you GLUT today, you are being abused. Please show some resistance. !!!
// !!! Nowadays, prefer using GLFW or SDL instead!
#include "imgui.h"

View File

@ -1,8 +1,8 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
set OUT_DIR=Debug
set OUT_EXE=example_sdl_directx11
set INCLUDES=/I.. /I..\.. /I%SDL2_DIR%\include /I "%WindowsSdkDir%Include\um" /I "%WindowsSdkDir%Include\shared" /I "%DXSDK_DIR%Include"
set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_dx11.cpp ..\..\imgui*.cpp
set LIBS=/libpath:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d11.lib d3dcompiler.lib
@set OUT_DIR=Debug
@set OUT_EXE=example_sdl_directx11
@set INCLUDES=/I..\.. /I..\..\backends /I%SDL2_DIR%\include /I "%WindowsSdkDir%Include\um" /I "%WindowsSdkDir%Include\shared" /I "%DXSDK_DIR%Include"
@set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_dx11.cpp ..\..\imgui*.cpp
@set LIBS=/LIBPATH:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d11.lib d3dcompiler.lib
mkdir %OUT_DIR%
cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console

View File

@ -1,8 +1,8 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
set OUT_DIR=Debug
set OUT_EXE=example_sdl_opengl2
set INCLUDES=/I.. /I..\.. /I%SDL2_DIR%\include
set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_opengl2.cpp ..\..\imgui*.cpp
set LIBS=/libpath:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib
@set OUT_DIR=Debug
@set OUT_EXE=example_sdl_opengl2
@set INCLUDES=/I..\.. /I..\..\backends /I%SDL2_DIR%\include
@set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_opengl2.cpp ..\..\imgui*.cpp
@set LIBS=/LIBPATH:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib
mkdir %OUT_DIR%
cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console

View File

@ -1,8 +1,8 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
set OUT_DIR=Debug
set OUT_EXE=example_sdl_opengl3
set INCLUDES=/I.. /I..\.. /I%SDL2_DIR%\include /I..\libs\gl3w
set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_opengl3.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c
set LIBS=/libpath:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib
@set OUT_DIR=Debug
@set OUT_EXE=example_sdl_opengl3
@set INCLUDES=/I..\.. /I..\..\backends /I%SDL2_DIR%\include /I..\libs\gl3w
@set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_opengl3.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c
@set LIBS=/LIBPATH:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib
mkdir %OUT_DIR%
cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console

View File

@ -1,4 +1,8 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
mkdir Debug
cl /nologo /Zi /MD /I .. /I ..\.. /I "%WindowsSdkDir%Include\um" /I "%WindowsSdkDir%Include\shared" /I "%DXSDK_DIR%Include" /D UNICODE /D _UNICODE *.cpp ..\..\backends\imgui_impl_win32.cpp ..\..\backends\imgui_impl_dx10.cpp ..\..\imgui*.cpp /FeDebug/example_win32_directx10.exe /FoDebug/ /link /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d10.lib d3dcompiler.lib
@set OUT_DIR=Debug
@set OUT_EXE=example_win32_directx10
@set INCLUDES=/I..\.. /I..\..\backends /I "%WindowsSdkDir%Include\um" /I "%WindowsSdkDir%Include\shared" /I "%DXSDK_DIR%Include"
@set SOURCES=main.cpp ..\..\backends\imgui_impl_win32.cpp ..\..\backends\imgui_impl_dx10.cpp ..\..\imgui*.cpp
@set LIBS=/LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d10.lib d3dcompiler.lib
mkdir %OUT_DIR%
cl /nologo /Zi /MD %INCLUDES% /D UNICODE /D _UNICODE %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%

View File

@ -1,4 +1,9 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
mkdir Debug
cl /nologo /Zi /MD /I .. /I ..\.. /I "%WindowsSdkDir%Include\um" /I "%WindowsSdkDir%Include\shared" /I "%DXSDK_DIR%Include" /D UNICODE /D _UNICODE *.cpp ..\..\backends\imgui_impl_dx11.cpp ..\..\backends\imgui_impl_win32.cpp ..\..\imgui*.cpp /FeDebug/example_win32_directx11.exe /FoDebug/ /link /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d11.lib d3dcompiler.lib
@set OUT_DIR=Debug
@set OUT_EXE=example_win32_directx11
@set INCLUDES=/I..\.. /I..\..\backends /I "%WindowsSdkDir%Include\um" /I "%WindowsSdkDir%Include\shared" /I "%DXSDK_DIR%Include"
@set SOURCES=main.cpp ..\..\backends\imgui_impl_dx11.cpp ..\..\backends\imgui_impl_win32.cpp ..\..\imgui*.cpp
@set LIBS=/LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d11.lib d3dcompiler.lib
mkdir %OUT_DIR%
cl /nologo /Zi /MD %INCLUDES% /D UNICODE /D _UNICODE %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%

View File

@ -1,5 +1,9 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
@REM Important: to build on 32-bit systems, the DX12 backends needs '#define ImTextureID ImU64', so we pass it here.
@set OUT_DIR=Debug
@set OUT_EXE=example_win32_directx12
@set INCLUDES=/I..\.. /I..\..\backends /I "%WindowsSdkDir%Include\um" /I "%WindowsSdkDir%Include\shared"
@set SOURCES=main.cpp ..\..\backends\imgui_impl_dx12.cpp ..\..\backends\imgui_impl_win32.cpp ..\..\imgui*.cpp
@set LIBS=d3d12.lib d3dcompiler.lib dxgi.lib
mkdir Debug
cl /nologo /Zi /MD /I .. /I ..\.. /I "%WindowsSdkDir%Include\um" /I "%WindowsSdkDir%Include\shared" /D ImTextureID=ImU64 /D UNICODE /D _UNICODE *.cpp ..\..\backends\imgui_impl_dx12.cpp ..\..\backends\imgui_impl_win32.cpp ..\..\imgui*.cpp /FeDebug/example_win32_directx12.exe /FoDebug/ /link d3d12.lib d3dcompiler.lib dxgi.lib
cl /nologo /Zi /MD %INCLUDES% /D ImTextureID=ImU64 /D UNICODE /D _UNICODE %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%

View File

@ -1,7 +1,10 @@
// Dear ImGui: standalone example application for DirectX 12
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Read online: https://github.com/ocornut/imgui/tree/master/docs
// FIXME: 64-bit only for now! (Because sizeof(ImTextureId) == sizeof(void*))
// Important: to compile on 32-bit systems, the DirectX12 backend requires code to be compiled with '#define ImTextureID ImU64'.
// This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*.
// This define is set in the example .vcxproj file and need to be replicated in your app or by adding it to your imconfig.h file.
#include "imgui.h"
#include "imgui_impl_win32.h"
@ -173,9 +176,11 @@ int main(int, char**)
}
// Rendering
FrameContext* frameCtxt = WaitForNextFrameResources();
ImGui::Render();
FrameContext* frameCtx = WaitForNextFrameResources();
UINT backBufferIdx = g_pSwapChain->GetCurrentBackBufferIndex();
frameCtxt->CommandAllocator->Reset();
frameCtx->CommandAllocator->Reset();
D3D12_RESOURCE_BARRIER barrier = {};
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
@ -184,13 +189,13 @@ int main(int, char**)
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
g_pd3dCommandList->Reset(frameCtxt->CommandAllocator, NULL);
g_pd3dCommandList->Reset(frameCtx->CommandAllocator, NULL);
g_pd3dCommandList->ResourceBarrier(1, &barrier);
// Render Dear ImGui graphics
g_pd3dCommandList->ClearRenderTargetView(g_mainRenderTargetDescriptor[backBufferIdx], (float*)&clear_color, 0, NULL);
g_pd3dCommandList->OMSetRenderTargets(1, &g_mainRenderTargetDescriptor[backBufferIdx], FALSE, NULL);
g_pd3dCommandList->SetDescriptorHeaps(1, &g_pd3dSrvDescHeap);
ImGui::Render();
ImGui_ImplDX12_RenderDrawData(ImGui::GetDrawData(), g_pd3dCommandList);
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
@ -205,10 +210,12 @@ int main(int, char**)
UINT64 fenceValue = g_fenceLastSignaledValue + 1;
g_pd3dCommandQueue->Signal(g_fence, fenceValue);
g_fenceLastSignaledValue = fenceValue;
frameCtxt->FenceValue = fenceValue;
frameCtx->FenceValue = fenceValue;
}
WaitForLastSubmittedFrame();
// Cleanup
ImGui_ImplDX12_Shutdown();
ImGui_ImplWin32_Shutdown();
ImGui::DestroyContext();
@ -382,13 +389,13 @@ void CleanupRenderTarget()
void WaitForLastSubmittedFrame()
{
FrameContext* frameCtxt = &g_frameContext[g_frameIndex % NUM_FRAMES_IN_FLIGHT];
FrameContext* frameCtx = &g_frameContext[g_frameIndex % NUM_FRAMES_IN_FLIGHT];
UINT64 fenceValue = frameCtxt->FenceValue;
UINT64 fenceValue = frameCtx->FenceValue;
if (fenceValue == 0)
return; // No fence was signaled
frameCtxt->FenceValue = 0;
frameCtx->FenceValue = 0;
if (g_fence->GetCompletedValue() >= fenceValue)
return;
@ -404,11 +411,11 @@ FrameContext* WaitForNextFrameResources()
HANDLE waitableObjects[] = { g_hSwapChainWaitableObject, NULL };
DWORD numWaitableObjects = 1;
FrameContext* frameCtxt = &g_frameContext[nextFrameIndex % NUM_FRAMES_IN_FLIGHT];
UINT64 fenceValue = frameCtxt->FenceValue;
FrameContext* frameCtx = &g_frameContext[nextFrameIndex % NUM_FRAMES_IN_FLIGHT];
UINT64 fenceValue = frameCtx->FenceValue;
if (fenceValue != 0) // means no fence was signaled
{
frameCtxt->FenceValue = 0;
frameCtx->FenceValue = 0;
g_fence->SetEventOnCompletion(fenceValue, g_fenceEvent);
waitableObjects[1] = g_fenceEvent;
numWaitableObjects = 2;
@ -416,7 +423,7 @@ FrameContext* WaitForNextFrameResources()
WaitForMultipleObjects(numWaitableObjects, waitableObjects, TRUE, INFINITE);
return frameCtxt;
return frameCtx;
}
void ResizeSwapChain(HWND hWnd, int width, int height)

View File

@ -1,3 +1,8 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
mkdir Debug
cl /nologo /Zi /MD /I .. /I ..\.. /I "%DXSDK_DIR%/Include" /D UNICODE /D _UNICODE *.cpp ..\..\backends\imgui_impl_dx9.cpp ..\..\backends\imgui_impl_win32.cpp ..\..\imgui*.cpp /FeDebug/example_win32_directx9.exe /FoDebug/ /link /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d9.lib
@set OUT_DIR=Debug
@set OUT_EXE=example_win32_directx9
@set INCLUDES=/I..\.. /I..\..\backends /I "%DXSDK_DIR%/Include"
@set SOURCES=main.cpp ..\..\backends\imgui_impl_dx9.cpp ..\..\backends\imgui_impl_win32.cpp ..\..\imgui*.cpp
@set LIBS=/LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d9.lib
mkdir %OUT_DIR%
cl /nologo /Zi /MD %INCLUDES% /D UNICODE /D _UNICODE %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%

View File

@ -53,16 +53,25 @@
//#define IMGUI_USE_WCHAR32
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
// By default the embedded implementations are declared static and not available outside of imgui cpp files.
// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
//---- Unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined, use the much faster STB sprintf library implementation of vsnprintf instead of the one from the default C library.
// Note that stb_sprintf.h is meant to be provided by the user and available in the include path at compile time. Also, the compatibility checks of the arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf.
//---- Use stb_printf's faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
// Requires 'stb_sprintf.h' to be available in the include path. Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf.
// #define IMGUI_USE_STB_SPRINTF
//---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
// Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided).
// On Windows you may use vcpkg with 'vcpkg install freetype' + 'vcpkg integrate install'.
//#define IMGUI_ENABLE_FREETYPE
//---- Use stb_truetype to build and rasterize the font atlas (default)
// The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
//#define IMGUI_ENABLE_STB_TRUETYPE
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
/*

641
imgui.cpp

File diff suppressed because it is too large Load Diff

532
imgui.h
View File

@ -1,4 +1,4 @@
// dear imgui, v1.80 WIP
// dear imgui, v1.81
// (headers)
// Help:
@ -19,27 +19,25 @@
/*
Index of this file:
// Header mess
// Forward declarations and basic types
// ImGui API (Dear ImGui end-user API)
// Flags & Enumerations
// Memory allocations macros
// ImVector<>
// ImGuiStyle
// ImGuiIO
// Misc data structures (ImGuiInputTextCallbackData, ImGuiSizeCallbackData, ImGuiPayload)
// Obsolete functions
// Helpers (ImGuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, ImColor)
// Draw List API (ImDrawCallback, ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawListFlags, ImDrawList, ImDrawData)
// Font API (ImFontConfig, ImFontGlyph, ImFontGlyphRangesBuilder, ImFontAtlasFlags, ImFontAtlas, ImFont)
// FIXME-TABLE: Add ImGuiTableSortSpecs and ImGuiTableColumnSortSpecs in "Misc data structures" section above (we don't do it right now to facilitate merging various branches)
// [SECTION] Header mess
// [SECTION] Forward declarations and basic types
// [SECTION] Dear ImGui end-user API functions
// [SECTION] Flags & Enumerations
// [SECTION] Helpers: Memory allocations macros, ImVector<>
// [SECTION] ImGuiStyle
// [SECTION] ImGuiIO
// [SECTION] Misc data structures (ImGuiInputTextCallbackData, ImGuiSizeCallbackData, ImGuiPayload, ImGuiTableSortSpecs, ImGuiTableColumnSortSpecs)
// [SECTION] Obsolete functions
// [SECTION] Helpers (ImGuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, ImColor)
// [SECTION] Drawing API (ImDrawCallback, ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawListFlags, ImDrawList, ImDrawData)
// [SECTION] Font API (ImFontConfig, ImFontGlyph, ImFontGlyphRangesBuilder, ImFontAtlasFlags, ImFontAtlas, ImFont)
// [SECTION] Viewports (ImGuiViewportFlags, ImGuiViewport)
*/
#pragma once
// Configuration file with compile-time options (edit imconfig.h or #define IMGUI_USER_CONFIG to your own filename)
// Configuration file with compile-time options (edit imconfig.h or '#define IMGUI_USER_CONFIG "myfilename.h" from your build system')
#ifdef IMGUI_USER_CONFIG
#include IMGUI_USER_CONFIG
#endif
@ -50,7 +48,7 @@ Index of this file:
#ifndef IMGUI_DISABLE
//-----------------------------------------------------------------------------
// Header mess
// [SECTION] Header mess
//-----------------------------------------------------------------------------
// Includes
@ -61,9 +59,10 @@ Index of this file:
// Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
#define IMGUI_VERSION "1.80 WIP"
#define IMGUI_VERSION_NUM 17906
#define IMGUI_VERSION "1.81"
#define IMGUI_VERSION_NUM 18100
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
#define IMGUI_HAS_TABLE
// Define attributes of all API symbols declarations (e.g. for DLL under Windows)
// IMGUI_API is used for core imgui functions, IMGUI_IMPL_API is used for the default backends files (imgui_impl_xxx.h)
@ -82,16 +81,18 @@ Index of this file:
#endif
#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR) / sizeof(*(_ARR)))) // Size of a static C-style array. Don't use on pointers!
#define IM_UNUSED(_VAR) ((void)(_VAR)) // Used to silence "unused variable warnings". Often useful as asserts may be stripped out from final builds.
#if (__cplusplus >= 201100)
#if (__cplusplus >= 201100) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201100)
#define IM_OFFSETOF(_TYPE,_MEMBER) offsetof(_TYPE, _MEMBER) // Offset of _MEMBER within _TYPE. Standardized as offsetof() in C++11
#else
#define IM_OFFSETOF(_TYPE,_MEMBER) ((size_t)&(((_TYPE*)0)->_MEMBER)) // Offset of _MEMBER within _TYPE. Old style macro.
#endif
// Helper Macros - IM_FMTARGS, IM_FMTLIST: Apply printf-style warnings to our formatting functions.
#if !defined(IMGUI_USE_STB_SPRINTF) && defined(__clang__)
#define IM_FMTARGS(FMT) __attribute__((format(printf, FMT, FMT+1))) // Apply printf-style warnings to our formatting functions.
#define IM_FMTARGS(FMT) __attribute__((format(printf, FMT, FMT+1)))
#define IM_FMTLIST(FMT) __attribute__((format(printf, FMT, 0)))
#elif !defined(IMGUI_USE_STB_SPRINTF) && defined(__GNUC__) && defined(__MINGW32__)
#define IM_FMTARGS(FMT) __attribute__((format(gnu_printf, FMT, FMT+1))) // Apply printf-style warnings to our formatting functions.
#define IM_FMTARGS(FMT) __attribute__((format(gnu_printf, FMT, FMT+1)))
#define IM_FMTLIST(FMT) __attribute__((format(gnu_printf, FMT, 0)))
#else
#define IM_FMTARGS(FMT)
@ -107,12 +108,12 @@ Index of this file:
#endif
#elif defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
#endif
//-----------------------------------------------------------------------------
// Forward declarations and basic types
// [SECTION] Forward declarations and basic types
//-----------------------------------------------------------------------------
// Forward declarations
@ -125,6 +126,7 @@ struct ImDrawListSplitter; // Helper to split a draw list into differen
struct ImDrawVert; // A single vertex (pos + uv + col = 20 bytes by default. Override layout with IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT)
struct ImFont; // Runtime data for a single font within a parent ImFontAtlas
struct ImFontAtlas; // Runtime data for multiple fonts, bake multiple fonts into a single texture, TTF/OTF font loader
struct ImFontBuilderIO; // Opaque interface to a font builder (stb_truetype or FreeType).
struct ImFontConfig; // Configuration data when adding a font or merging fonts
struct ImFontGlyph; // A single font glyph (code point + coordinates within in ImFontAtlas + offset)
struct ImFontGlyphRangesBuilder; // Helper to build glyph ranges from text/string data
@ -142,6 +144,7 @@ struct ImGuiTableSortSpecs; // Sorting specifications for a table (often
struct ImGuiTableColumnSortSpecs; // Sorting specification for one column of a table
struct ImGuiTextBuffer; // Helper to hold and append into a text buffer (~string builder)
struct ImGuiTextFilter; // Helper to parse and apply text filters (e.g. "aaaaa[,bbbbb][,ccccc]")
struct ImGuiViewport; // A Platform Window (always only one in 'master' branch), in the future may represent Platform Monitor
// Enums/Flags (declared as int for compatibility with old C++, to allow using as flags and to not pollute the top of this file)
// - Tip: Use your programming IDE navigation facilities on the names in the _central column_ below to find the actual flags/enum lists!
@ -180,6 +183,7 @@ typedef int ImGuiTableFlags; // -> enum ImGuiTableFlags_ // Flags: F
typedef int ImGuiTableColumnFlags; // -> enum ImGuiTableColumnFlags_// Flags: For TableSetupColumn()
typedef int ImGuiTableRowFlags; // -> enum ImGuiTableRowFlags_ // Flags: For TableNextRow()
typedef int ImGuiTreeNodeFlags; // -> enum ImGuiTreeNodeFlags_ // Flags: for TreeNode(), TreeNodeEx(), CollapsingHeader()
typedef int ImGuiViewportFlags; // -> enum ImGuiViewportFlags_ // Flags: for ImGuiViewport
typedef int ImGuiWindowFlags; // -> enum ImGuiWindowFlags_ // Flags: for Begin(), BeginChild()
// Other types
@ -187,10 +191,10 @@ typedef int ImGuiWindowFlags; // -> enum ImGuiWindowFlags_ // Flags: f
typedef void* ImTextureID; // User data for rendering backend to identify a texture. This is whatever to you want it to be! read the FAQ about ImTextureID for details.
#endif
typedef unsigned int ImGuiID; // A unique ID used by widgets, typically hashed from a stack of string.
typedef int (*ImGuiInputTextCallback)(ImGuiInputTextCallbackData* data);
typedef void (*ImGuiSizeCallback)(ImGuiSizeCallbackData* data);
typedef int (*ImGuiInputTextCallback)(ImGuiInputTextCallbackData* data); // Callback function for ImGui::InputText()
typedef void (*ImGuiSizeCallback)(ImGuiSizeCallbackData* data); // Callback function for ImGui::SetNextWindowSizeConstraints()
// Decoded character types
// Character types
// (we generally use UTF-8 encoded string in the API. This is storage specifically for a decoded character used for keyboard input and display)
typedef unsigned short ImWchar16; // A single decoded U16 character/code point. We encode them as multi bytes UTF-8 when used in strings.
typedef unsigned int ImWchar32; // A single decoded U32 character/code point. We encode them as multi bytes UTF-8 when used in strings.
@ -235,8 +239,8 @@ struct ImVec2
// 4D vector (often used to store floating-point colors)
struct ImVec4
{
float x, y, z, w;
ImVec4() { x = y = z = w = 0.0f; }
float x, y, z, w;
ImVec4() { x = y = z = w = 0.0f; }
ImVec4(float _x, float _y, float _z, float _w) { x = _x; y = _y; z = _z; w = _w; }
#ifdef IM_VEC4_CLASS_EXTRA
IM_VEC4_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec4.
@ -244,8 +248,8 @@ struct ImVec4
};
//-----------------------------------------------------------------------------
// ImGui: Dear ImGui end-user API
// (This is a namespace. You can add extra ImGui:: functions in your own separate file. Please don't modify imgui source files!)
// [SECTION] Dear ImGui end-user API functions
// (Note that ImGui:: being a namespace, you can add extra ImGui:: functions in your own separate file. Please don't modify imgui source files!)
//-----------------------------------------------------------------------------
namespace ImGui
@ -267,19 +271,19 @@ namespace ImGui
IMGUI_API ImDrawData* GetDrawData(); // valid after Render() and until the next call to NewFrame(). this is what you have to render.
// Demo, Debug, Information
IMGUI_API void ShowDemoWindow(bool* p_open = NULL); // create Demo window (previously called ShowTestWindow). demonstrate most ImGui features. call this to learn about the library! try to make it always available in your application!
IMGUI_API void ShowAboutWindow(bool* p_open = NULL); // create About window. display Dear ImGui version, credits and build/system information.
IMGUI_API void ShowDemoWindow(bool* p_open = NULL); // create Demo window. demonstrate most ImGui features. call this to learn about the library! try to make it always available in your application!
IMGUI_API void ShowMetricsWindow(bool* p_open = NULL); // create Metrics/Debugger window. display Dear ImGui internals: windows, draw commands, various internal state, etc.
IMGUI_API void ShowAboutWindow(bool* p_open = NULL); // create About window. display Dear ImGui version, credits and build/system information.
IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL); // add style editor block (not a window). you can pass in a reference ImGuiStyle structure to compare to, revert to and save to (else it uses the default style)
IMGUI_API bool ShowStyleSelector(const char* label); // add style selector block (not a window), essentially a combo listing the default styles.
IMGUI_API void ShowFontSelector(const char* label); // add font selector block (not a window), essentially a combo listing the loaded fonts.
IMGUI_API void ShowUserGuide(); // add basic help/info block (not a window): how to manipulate ImGui as a end-user (mouse/keyboard controls).
IMGUI_API const char* GetVersion(); // get the compiled version string e.g. "1.23" (essentially the compiled value for IMGUI_VERSION)
IMGUI_API const char* GetVersion(); // get the compiled version string e.g. "1.80 WIP" (essentially the value for IMGUI_VERSION from the compiled version of imgui.cpp)
// Styles
IMGUI_API void StyleColorsDark(ImGuiStyle* dst = NULL); // new, recommended style (default)
IMGUI_API void StyleColorsClassic(ImGuiStyle* dst = NULL); // classic imgui style
IMGUI_API void StyleColorsLight(ImGuiStyle* dst = NULL); // best used with borders and a custom, thicker font
IMGUI_API void StyleColorsClassic(ImGuiStyle* dst = NULL); // classic imgui style
// Windows
// - Begin() = push window to the stack and start appending to it. End() = pop window from the stack.
@ -339,20 +343,21 @@ namespace ImGui
IMGUI_API void SetWindowFocus(const char* name); // set named window to be focused / top-most. use NULL to remove focus.
// Content region
// - Those functions are bound to be redesigned soon (they are confusing, incomplete and return values in local window coordinates which increases confusion)
IMGUI_API ImVec2 GetContentRegionMax(); // current content boundaries (typically window boundaries including scrolling, or current column boundaries), in windows coordinates
// - Retrieve available space from a given point. GetContentRegionAvail() is frequently useful.
// - Those functions are bound to be redesigned (they are confusing, incomplete and the Min/Max return values are in local window coordinates which increases confusion)
IMGUI_API ImVec2 GetContentRegionAvail(); // == GetContentRegionMax() - GetCursorPos()
IMGUI_API ImVec2 GetContentRegionMax(); // current content boundaries (typically window boundaries including scrolling, or current column boundaries), in windows coordinates
IMGUI_API ImVec2 GetWindowContentRegionMin(); // content boundaries min (roughly (0,0)-Scroll), in window coordinates
IMGUI_API ImVec2 GetWindowContentRegionMax(); // content boundaries max (roughly (0,0)+Size-Scroll) where Size can be override with SetNextWindowContentSize(), in window coordinates
IMGUI_API float GetWindowContentRegionWidth(); //
// Windows Scrolling
IMGUI_API float GetScrollX(); // get scrolling amount [0..GetScrollMaxX()]
IMGUI_API float GetScrollY(); // get scrolling amount [0..GetScrollMaxY()]
IMGUI_API float GetScrollMaxX(); // get maximum scrolling amount ~~ ContentSize.x - WindowSize.x
IMGUI_API float GetScrollMaxY(); // get maximum scrolling amount ~~ ContentSize.y - WindowSize.y
IMGUI_API void SetScrollX(float scroll_x); // set scrolling amount [0..GetScrollMaxX()]
IMGUI_API void SetScrollY(float scroll_y); // set scrolling amount [0..GetScrollMaxY()]
IMGUI_API float GetScrollX(); // get scrolling amount [0 .. GetScrollMaxX()]
IMGUI_API float GetScrollY(); // get scrolling amount [0 .. GetScrollMaxY()]
IMGUI_API void SetScrollX(float scroll_x); // set scrolling amount [0 .. GetScrollMaxX()]
IMGUI_API void SetScrollY(float scroll_y); // set scrolling amount [0 .. GetScrollMaxY()]
IMGUI_API float GetScrollMaxX(); // get maximum scrolling amount ~~ ContentSize.x - WindowSize.x - DecorationsSize.x
IMGUI_API float GetScrollMaxY(); // get maximum scrolling amount ~~ ContentSize.y - WindowSize.y - DecorationsSize.y
IMGUI_API void SetScrollHereX(float center_x_ratio = 0.5f); // adjust scrolling amount to make current cursor position visible. center_x_ratio=0.0: left, 0.5: center, 1.0: right. When using to make a "default/current item" visible, consider using SetItemDefaultFocus() instead.
IMGUI_API void SetScrollHereY(float center_y_ratio = 0.5f); // adjust scrolling amount to make current cursor position visible. center_y_ratio=0.0: top, 0.5: center, 1.0: bottom. When using to make a "default/current item" visible, consider using SetItemDefaultFocus() instead.
IMGUI_API void SetScrollFromPosX(float local_x, float center_x_ratio = 0.5f); // adjust scrolling amount to make given position visible. Generally GetCursorStartPos() + offset to compute a valid position.
@ -361,32 +366,34 @@ namespace ImGui
// Parameters stacks (shared)
IMGUI_API void PushFont(ImFont* font); // use NULL as a shortcut to push default font
IMGUI_API void PopFont();
IMGUI_API void PushStyleColor(ImGuiCol idx, ImU32 col);
IMGUI_API void PushStyleColor(ImGuiCol idx, ImU32 col); // modify a style color. always use this if you modify the style after NewFrame().
IMGUI_API void PushStyleColor(ImGuiCol idx, const ImVec4& col);
IMGUI_API void PopStyleColor(int count = 1);
IMGUI_API void PushStyleVar(ImGuiStyleVar idx, float val);
IMGUI_API void PushStyleVar(ImGuiStyleVar idx, const ImVec2& val);
IMGUI_API void PushStyleVar(ImGuiStyleVar idx, float val); // modify a style float variable. always use this if you modify the style after NewFrame().
IMGUI_API void PushStyleVar(ImGuiStyleVar idx, const ImVec2& val); // modify a style ImVec2 variable. always use this if you modify the style after NewFrame().
IMGUI_API void PopStyleVar(int count = 1);
IMGUI_API void PushAllowKeyboardFocus(bool allow_keyboard_focus); // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets
IMGUI_API void PopAllowKeyboardFocus();
IMGUI_API void PushButtonRepeat(bool repeat); // in 'repeat' mode, Button*() functions return repeated true in a typematic manner (using io.KeyRepeatDelay/io.KeyRepeatRate setting). Note that you can call IsItemActive() after any Button() to tell if the button is held in the current frame.
IMGUI_API void PopButtonRepeat();
IMGUI_API const ImVec4& GetStyleColorVec4(ImGuiCol idx); // retrieve style color as stored in ImGuiStyle structure. use to feed back into PushStyleColor(), otherwise use GetColorU32() to get style color with style alpha baked in.
IMGUI_API ImFont* GetFont(); // get current font
IMGUI_API float GetFontSize(); // get current font size (= height in pixels) of current font with current scale applied
IMGUI_API ImVec2 GetFontTexUvWhitePixel(); // get UV coordinate for a while pixel, useful to draw custom shapes via the ImDrawList API
IMGUI_API ImU32 GetColorU32(ImGuiCol idx, float alpha_mul = 1.0f); // retrieve given style color with style alpha applied and optional extra alpha multiplier
IMGUI_API ImU32 GetColorU32(const ImVec4& col); // retrieve given color with style alpha applied
IMGUI_API ImU32 GetColorU32(ImU32 col); // retrieve given color with style alpha applied
// Parameters stacks (current window)
IMGUI_API void PushItemWidth(float item_width); // push width of items for common large "item+label" widgets. >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -FLT_MIN always align width to the right side). 0.0f = default to ~2/3 of windows width,
IMGUI_API void PushItemWidth(float item_width); // push width of items for common large "item+label" widgets. >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -FLT_MIN always align width to the right side).
IMGUI_API void PopItemWidth();
IMGUI_API void SetNextItemWidth(float item_width); // set width of the _next_ common large "item+label" widget. >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -FLT_MIN always align width to the right side)
IMGUI_API float CalcItemWidth(); // width of item given pushed settings and current cursor position. NOT necessarily the width of last item unlike most 'Item' functions.
IMGUI_API void PushTextWrapPos(float wrap_local_pos_x = 0.0f); // push word-wrapping position for Text*() commands. < 0.0f: no wrapping; 0.0f: wrap to end of window (or column); > 0.0f: wrap at 'wrap_pos_x' position in window local space
IMGUI_API void PopTextWrapPos();
// Style read access
IMGUI_API ImFont* GetFont(); // get current font
IMGUI_API float GetFontSize(); // get current font size (= height in pixels) of current font with current scale applied
IMGUI_API ImVec2 GetFontTexUvWhitePixel(); // get UV coordinate for a while pixel, useful to draw custom shapes via the ImDrawList API
IMGUI_API ImU32 GetColorU32(ImGuiCol idx, float alpha_mul = 1.0f); // retrieve given style color with style alpha applied and optional extra alpha multiplier, packed as a 32-bit value suitable for ImDrawList
IMGUI_API ImU32 GetColorU32(const ImVec4& col); // retrieve given color with style alpha applied, packed as a 32-bit value suitable for ImDrawList
IMGUI_API ImU32 GetColorU32(ImU32 col); // retrieve given color with style alpha applied, packed as a 32-bit value suitable for ImDrawList
IMGUI_API const ImVec4& GetStyleColorVec4(ImGuiCol idx); // retrieve style color as stored in ImGuiStyle structure. use to feed back into PushStyleColor(), otherwise use GetColorU32() to get style color with style alpha baked in.
// Cursor / Layout
// - By "cursor" we mean the current output position.
// - The typical widget behavior is to output themselves at the current cursor position, then move the cursor one line down.
@ -410,8 +417,8 @@ namespace ImGui
IMGUI_API void SetCursorPosX(float local_x); // GetWindowPos() + GetCursorPos() == GetCursorScreenPos() etc.)
IMGUI_API void SetCursorPosY(float local_y); //
IMGUI_API ImVec2 GetCursorStartPos(); // initial cursor position in window coordinates
IMGUI_API ImVec2 GetCursorScreenPos(); // cursor position in absolute screen coordinates [0..io.DisplaySize] (useful to work with ImDrawList API)
IMGUI_API void SetCursorScreenPos(const ImVec2& pos); // cursor position in absolute screen coordinates [0..io.DisplaySize]
IMGUI_API ImVec2 GetCursorScreenPos(); // cursor position in absolute coordinates (useful to work with ImDrawList API). generally top-left == GetMainViewport()->Pos == (0,0) in single viewport mode, and bottom-right == GetMainViewport()->Pos+Size == io.DisplaySize in single-viewport mode.
IMGUI_API void SetCursorScreenPos(const ImVec2& pos); // cursor position in absolute coordinates
IMGUI_API void AlignTextToFramePadding(); // vertically align upcoming text baseline to FramePadding.y so that it will align properly to regularly framed items (call if you have text on a line before a framed item)
IMGUI_API float GetTextLineHeight(); // ~ FontSize
IMGUI_API float GetTextLineHeightWithSpacing(); // ~ FontSize + style.ItemSpacing.y (distance in pixels between 2 consecutive lines of text)
@ -463,12 +470,12 @@ namespace ImGui
IMGUI_API bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value);
IMGUI_API bool RadioButton(const char* label, bool active); // use with e.g. if (RadioButton("one", my_value==1)) { my_value = 1; }
IMGUI_API bool RadioButton(const char* label, int* v, int v_button); // shortcut to handle the above pattern when value is an integer
IMGUI_API void ProgressBar(float fraction, const ImVec2& size_arg = ImVec2(-1, 0), const char* overlay = NULL);
IMGUI_API void ProgressBar(float fraction, const ImVec2& size_arg = ImVec2(-FLT_MIN, 0), const char* overlay = NULL);
IMGUI_API void Bullet(); // draw a small circle + keep the cursor on the same line. advance cursor x position by GetTreeNodeToLabelSpacing(), same distance that TreeNode() uses
// Widgets: Combo Box
// - The BeginCombo()/EndCombo() api allows you to manage your contents and selection state however you want it, by creating e.g. Selectable() items.
// - The old Combo() api are helpers over BeginCombo()/EndCombo() which are kept available for convenience purpose.
// - The old Combo() api are helpers over BeginCombo()/EndCombo() which are kept available for convenience purpose. This is analogous to how ListBox are created.
IMGUI_API bool BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags = 0);
IMGUI_API void EndCombo(); // only call EndCombo() if BeginCombo() returns true!
IMGUI_API bool Combo(const char* label, int* current_item, const char* const items[], int items_count, int popup_max_height_in_items = -1);
@ -565,7 +572,7 @@ namespace ImGui
IMGUI_API void TreePop(); // ~ Unindent()+PopId()
IMGUI_API float GetTreeNodeToLabelSpacing(); // horizontal distance preceding label when using TreeNode*() or Bullet() == (g.FontSize + style.FramePadding.x*2) for a regular unframed TreeNode
IMGUI_API bool CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags = 0); // if returning 'true' the header is open. doesn't indent nor push on ID stack. user doesn't have to call TreePop().
IMGUI_API bool CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags flags = 0); // when 'p_open' isn't NULL, display an additional small close button on upper right of the header
IMGUI_API bool CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFlags flags = 0); // when 'p_visible != NULL': if '*p_visible==true' display an additional small close button on upper right of the header which will set the bool to false when clicked, if '*p_visible==false' don't display the header.
IMGUI_API void SetNextItemOpen(bool is_open, ImGuiCond cond = 0); // set next TreeNode/CollapsingHeader open state.
// Widgets: Selectables
@ -575,14 +582,18 @@ namespace ImGui
IMGUI_API bool Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0, 0)); // "bool* p_selected" point to the selection state (read-write), as a convenient helper.
// Widgets: List Boxes
// - FIXME: To be consistent with all the newer API, ListBoxHeader/ListBoxFooter should in reality be called BeginListBox/EndListBox. Will rename them.
// - This is essentially a thin wrapper to using BeginChild/EndChild with some stylistic changes.
// - The BeginListBox()/EndListBox() api allows you to manage your contents and selection state however you want it, by creating e.g. Selectable() or any items.
// - The simplified/old ListBox() api are helpers over BeginListBox()/EndListBox() which are kept available for convenience purpose. This is analoguous to how Combos are created.
// - Choose frame width: size.x > 0.0f: custom / size.x < 0.0f or -FLT_MIN: right-align / size.x = 0.0f (default): use current ItemWidth
// - Choose frame height: size.y > 0.0f: custom / size.y < 0.0f or -FLT_MIN: bottom-align / size.y = 0.0f (default): arbitrary default height which can fit ~7 items
IMGUI_API bool BeginListBox(const char* label, const ImVec2& size = ImVec2(0, 0)); // open a framed scrolling region
IMGUI_API void EndListBox(); // only call EndListBox() if BeginListBox() returned true!
IMGUI_API bool ListBox(const char* label, int* current_item, const char* const items[], int items_count, int height_in_items = -1);
IMGUI_API bool ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1);
IMGUI_API bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0, 0)); // use if you want to reimplement ListBox() will custom data or interactions. if the function return true, you can output elements then call ListBoxFooter() afterwards.
IMGUI_API bool ListBoxHeader(const char* label, int items_count, int height_in_items = -1); // "
IMGUI_API void ListBoxFooter(); // terminate the scrolling region. only call ListBoxFooter() if ListBoxHeader() returned true!
// Widgets: Data Plotting
// - Consider using ImPlot (https://github.com/epezent/implot)
IMGUI_API void PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0), int stride = sizeof(float));
IMGUI_API void PlotLines(const char* label, float(*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0));
IMGUI_API void PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0), int stride = sizeof(float));
@ -609,7 +620,7 @@ namespace ImGui
IMGUI_API bool MenuItem(const char* label, const char* shortcut, bool* p_selected, bool enabled = true); // return true when activated + toggle (*p_selected) if p_selected != NULL
// Tooltips
// - Tooltip are windows following the mouse which do not take focus away.
// - Tooltip are windows following the mouse. They do not take focus away.
IMGUI_API void BeginTooltip(); // begin/append a tooltip window. to create full-featured tooltip (with any kind of items).
IMGUI_API void EndTooltip();
IMGUI_API void SetTooltip(const char* fmt, ...) IM_FMTARGS(1); // set a text-only tooltip, typically use with ImGui::IsItemHovered(). override any previous call to SetTooltip().
@ -653,63 +664,62 @@ namespace ImGui
IMGUI_API bool IsPopupOpen(const char* str_id, ImGuiPopupFlags flags = 0); // return true if the popup is open.
// Tables
// [BETA API] API may evolve!
// [BETA API] API may evolve slightly! If you use this, please update to the next version when it comes out!
// - Full-featured replacement for old Columns API.
// - See Demo->Tables for details.
// - See Demo->Tables for demo code.
// - See top of imgui_tables.cpp for general commentary.
// - See ImGuiTableFlags_ and ImGuiTableColumnFlags_ enums for a description of available flags.
// The typical call flow is:
// - 1. Call BeginTable()
// - 2. Optionally call TableSetupColumn() to submit column name/flags/defaults
// - 3. Optionally call TableSetupScrollFreeze() to request scroll freezing of columns/rows
// - 4. Optionally call TableHeadersRow() to submit a header row (names will be pulled from data submitted to TableSetupColumns)
// - 5. Populate contents
// - 1. Call BeginTable().
// - 2. Optionally call TableSetupColumn() to submit column name/flags/defaults.
// - 3. Optionally call TableSetupScrollFreeze() to request scroll freezing of columns/rows.
// - 4. Optionally call TableHeadersRow() to submit a header row. Names are pulled from TableSetupColumn() data.
// - 5. Populate contents:
// - In most situations you can use TableNextRow() + TableSetColumnIndex(N) to start appending into a column.
// - If you are using tables as a sort of grid, where every columns is holding the same type of contents,
// you may prefer using TableNextColumn() instead of TableNextRow() + TableSetColumnIndex().
// TableNextColumn() will automatically wrap-around into the next row if needed.
// - IMPORTANT: Comparatively to the old Columns() API, we need to call TableNextColumn() for the first column!
// - Both TableSetColumnIndex() and TableNextColumn() return true when the column is visible or performing
// width measurements. Otherwise, you may skip submitting the contents of a cell/column, BUT ONLY if you know
// it is not going to contribute to row height.
// In many situations, you may skip submitting contents for every columns but one (e.g. the first one).
// - Summary of possible call flow:
// ----------------------------------------------------------------------------------------------------------
// TableNextRow() -> TableSetColumnIndex(0) -> Text("Hello 0") -> TableSetColumnIndex(1) -> Text("Hello 1") // OK
// TableNextRow() -> TableNextColumn() -> Text("Hello 0") -> TableNextColumn() -> Text("Hello 1") // OK
// TableNextColumn() -> Text("Hello 0") -> TableNextColumn() -> Text("Hello 1") // OK: TableNextColumn() automatically gets to next row!
// TableNextRow() -> Text("Hello 0") // Not OK! Missing TableSetColumnIndex() or TableNextColumn()! Text will not appear!
// ----------------------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------
// TableNextRow() -> TableSetColumnIndex(0) -> Text("Hello 0") -> TableSetColumnIndex(1) -> Text("Hello 1") // OK
// TableNextRow() -> TableNextColumn() -> Text("Hello 0") -> TableNextColumn() -> Text("Hello 1") // OK
// TableNextColumn() -> Text("Hello 0") -> TableNextColumn() -> Text("Hello 1") // OK: TableNextColumn() automatically gets to next row!
// TableNextRow() -> Text("Hello 0") // Not OK! Missing TableSetColumnIndex() or TableNextColumn()! Text will not appear!
// --------------------------------------------------------------------------------------------------------
// - 5. Call EndTable()
#define IMGUI_HAS_TABLE 1
IMGUI_API bool BeginTable(const char* str_id, int columns_count, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(0, 0), float inner_width = 0.0f);
IMGUI_API bool BeginTable(const char* str_id, int column, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(0.0f, 0.0f), float inner_width = 0.0f);
IMGUI_API void EndTable(); // only call EndTable() if BeginTable() returns true!
IMGUI_API void TableNextRow(ImGuiTableRowFlags row_flags = 0, float min_row_height = 0.0f); // append into the first cell of a new row.
IMGUI_API bool TableNextColumn(); // append into the next column (or first column of next row if currently in last column). Return true when column is visible.
IMGUI_API bool TableSetColumnIndex(int column_n); // append into the specified column. Return true when column is visible.
IMGUI_API int TableGetColumnIndex(); // return current column index.
IMGUI_API int TableGetRowIndex(); // return current row index.
// Tables: Headers & Columns declaration
// - Use TableSetupColumn() to specify label, resizing policy, default width/weight, id, various other flags etc.
// Important: this will not display anything! The name passed to TableSetupColumn() is used by TableHeadersRow() and context-menus.
// - Use TableHeadersRow() to create a row and automatically submit a TableHeader() for each column.
// Headers are required to perform: reordering, sorting, and opening the context menu (but context menu can also be available in columns body using ImGuiTableFlags_ContextMenuInBody).
// - You may manually submit headers using TableNextRow() + TableHeader() calls, but this is only useful in some advanced cases (e.g. adding custom widgets in header row).
// - Use TableSetupScrollFreeze() to lock columns (from the right) or rows (from the top) so they stay visible when scrolled.
IMGUI_API void TableSetupColumn(const char* label, ImGuiTableColumnFlags flags = 0, float init_width_or_weight = -1.0f, ImU32 user_id = 0);
// - Use TableHeadersRow() to create a header row and automatically submit a TableHeader() for each column.
// Headers are required to perform: reordering, sorting, and opening the context menu.
// The context menu can also be made available in columns body using ImGuiTableFlags_ContextMenuInBody.
// - You may manually submit headers using TableNextRow() + TableHeader() calls, but this is only useful in
// some advanced use cases (e.g. adding custom widgets in header row).
// - Use TableSetupScrollFreeze() to lock columns/rows so they stay visible when scrolled.
IMGUI_API void TableSetupColumn(const char* label, ImGuiTableColumnFlags flags = 0, float init_width_or_weight = 0.0f, ImU32 user_id = 0);
IMGUI_API void TableSetupScrollFreeze(int cols, int rows); // lock columns/rows so they stay visible when scrolled.
IMGUI_API void TableHeadersRow(); // submit all headers cells based on data provided to TableSetupColumn() + submit context menu
IMGUI_API void TableHeader(const char* label); // submit one header cell manually (rarely used)
// Tables: Sorting
// - Call TableGetSortSpecs() to retrieve latest sort specs for the table. NULL when not sorting.
// - When 'SpecsDirty == true' you should sort your data. It will be true when sorting specs have changed
// since last call, or the first time. Make sure to set 'SpecsDirty = false' after sorting, else you may
// wastefully sort your data every frame!
// - Lifetime: don't hold on this pointer over multiple frames or past any subsequent call to BeginTable().
IMGUI_API ImGuiTableSortSpecs* TableGetSortSpecs(); // get latest sort specs for the table (NULL if not sorting).
// Tables: Miscellaneous functions
// - Most functions taking 'int column_n' treat the default value of -1 as the same as passing the current column index
// - Sorting: call TableGetSortSpecs() to retrieve latest sort specs for the table. Return value will be NULL if no sorting.
// When 'SpecsDirty == true' you should sort your data. It will be true when sorting specs have changed since last call, or the first time.
// Make sure to set 'SpecsDirty = false' after sorting, else you may wastefully sort your data every frame!
// Lifetime: don't hold on this pointer over multiple frames or past any subsequent call to BeginTable().
// - Functions args 'int column_n' treat the default value of -1 as the same as passing the current column index.
IMGUI_API int TableGetColumnCount(); // return number of columns (value passed to BeginTable)
IMGUI_API int TableGetColumnIndex(); // return current column index.
IMGUI_API int TableGetRowIndex(); // return current row index.
IMGUI_API const char* TableGetColumnName(int column_n = -1); // return "" if column didn't have a name declared by TableSetupColumn(). Pass -1 to use current column.
IMGUI_API ImGuiTableColumnFlags TableGetColumnFlags(int column_n = -1); // return column flags so you can query their Enabled/Visible/Sorted/Hovered status flags.
IMGUI_API ImGuiTableSortSpecs* TableGetSortSpecs(); // get latest sort specs for the table (NULL if not sorting).
IMGUI_API void TableSetBgColor(ImGuiTableBgTarget bg_target, ImU32 color, int column_n = -1); // change the color of a cell, row, or column. See ImGuiTableBgTarget_ flags for details.
IMGUI_API ImGuiTableColumnFlags TableGetColumnFlags(int column_n = -1); // return column flags so you can query their Enabled/Visible/Sorted/Hovered status flags. Pass -1 to use current column.
IMGUI_API void TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n = -1); // change the color of a cell, row, or column. See ImGuiTableBgTarget_ flags for details.
// Legacy Columns API (2020: prefer using Tables!)
// - You can also use SameLine(pos_x) to mimic simplified columns.
@ -740,7 +750,6 @@ namespace ImGui
IMGUI_API void LogText(const char* fmt, ...) IM_FMTARGS(1); // pass text data straight to log (without being displayed)
// Drag and Drop
// - [BETA API] API may evolve!
// - If you stop calling BeginDragDropSource() the payload is preserved however it won't have a preview tooltip (we currently display a fallback "..." tooltip as replacement)
IMGUI_API bool BeginDragDropSource(ImGuiDragDropFlags flags = 0); // call when the current item is active. If this return true, you can call SetDragDropPayload() + EndDragDropSource()
IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t sz, ImGuiCond cond = 0); // type is a user defined string of maximum 32 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui.
@ -751,6 +760,7 @@ namespace ImGui
IMGUI_API const ImGuiPayload* GetDragDropPayload(); // peek directly into the current payload from anywhere. may return NULL. use ImGuiPayload::IsDataType() to test for the payload type.
// Clipping
// - Mouse hovering is affected by ImGui::PushClipRect() calls, unlike direct calls to ImDrawList::PushClipRect() which are render only.
IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect);
IMGUI_API void PopClipRect();
@ -780,6 +790,12 @@ namespace ImGui
IMGUI_API ImVec2 GetItemRectSize(); // get size of last item
IMGUI_API void SetItemAllowOverlap(); // allow last item to be overlapped by a subsequent item. sometimes useful with invisible buttons, selectables, etc. to catch unused area.
// Viewports
// - Currently represents the Platform Window created by the application which is hosting our Dear ImGui windows.
// - In 'docking' branch with multi-viewport enabled, we extend this concept to have multiple active viewports.
// - In the future we will extend this concept further to also represent Platform Monitor and support a "no main platform window" operation mode.
IMGUI_API ImGuiViewport* GetMainViewport(); // return primary/default viewport.
// Miscellaneous Utilities
IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle (of given size, starting from cursor position) is visible / not clipped.
IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side.
@ -860,7 +876,7 @@ namespace ImGui
} // namespace ImGui
//-----------------------------------------------------------------------------
// Flags & Enumerations
// [SECTION] Flags & Enumerations
//-----------------------------------------------------------------------------
// Flags for ImGui::Begin()
@ -1033,98 +1049,122 @@ enum ImGuiTabItemFlags_
};
// Flags for ImGui::BeginTable()
// - Important! Sizing policies have particularly complex and subtle side effects, more so than you would expect.
// [BETA API] API may evolve slightly! If you use this, please update to the next version when it comes out!
// - Important! Sizing policies have complex and subtle side effects, more so than you would expect.
// Read comments/demos carefully + experiment with live demos to get acquainted with them.
// - The default sizing policy for columns depends on whether the ScrollX flag is set on the table:
// When ScrollX is off:
// - Table defaults to ImGuiTableFlags_ColumnsWidthStretch -> all Columns defaults to ImGuiTableColumnFlags_WidthStretch.
// - Columns sizing policy allowed: Stretch (default) or Fixed/Auto.
// - Stretch Columns will share the width available in table.
// - Fixed Columns will generally obtain their requested width unless the Table cannot fit them all.
// When ScrollX is on:
// - Table defaults to ImGuiTableFlags_ColumnsWidthFixed -> all Columns defaults to ImGuiTableColumnFlags_WidthFixed.
// - Columns sizing policy allowed: Fixed/Auto mostly!
// - The DEFAULT sizing policies are:
// - Default to ImGuiTableFlags_SizingFixedFit if ScrollX is on, or if host window has ImGuiWindowFlags_AlwaysAutoResize.
// - Default to ImGuiTableFlags_SizingStretchSame if ScrollX is off.
// - When ScrollX is off:
// - Table defaults to ImGuiTableFlags_SizingStretchSame -> all Columns defaults to ImGuiTableColumnFlags_WidthStretch with same weight.
// - Columns sizing policy allowed: Stretch (default), Fixed/Auto.
// - Fixed Columns will generally obtain their requested width (unless the table cannot fit them all).
// - Stretch Columns will share the remaining width.
// - Mixed Fixed/Stretch columns is possible but has various side-effects on resizing behaviors.
// The typical use of mixing sizing policies is: any number of LEADING Fixed columns, followed by one or two TRAILING Stretch columns.
// (this is because the visible order of columns have subtle but necessary effects on how they react to manual resizing).
// - When ScrollX is on:
// - Table defaults to ImGuiTableFlags_SizingFixedFit -> all Columns defaults to ImGuiTableColumnFlags_WidthFixed
// - Columns sizing policy allowed: Fixed/Auto mostly.
// - Fixed Columns can be enlarged as needed. Table will show an horizontal scrollbar if needed.
// - When using auto-resizing (non-resizable) fixed columns, querying the content width to use item right-alignment e.g. SetNextItemWidth(-FLT_MIN) doesn't make sense, would create a feedback loop.
// - Using Stretch columns OFTEN DOES NOT MAKE SENSE if ScrollX is on, UNLESS you have specified a value for 'inner_width' in BeginTable().
// - Mixing up columns with different sizing policy is possible BUT can be tricky and has some side-effects and restrictions.
// (their visible order and the scrolling state have subtle but necessary effects on how they can be manually resized).
// The typical use of mixing sizing policies is to have ScrollX disabled, one or two Stretch Column and many Fixed Columns.
// If you specify a value for 'inner_width' then effectively the scrolling space is known and Stretch or mixed Fixed/Stretch columns become meaningful again.
// - Read on documentation at the top of imgui_tables.cpp for details.
enum ImGuiTableFlags_
{
// Features
ImGuiTableFlags_None = 0,
ImGuiTableFlags_Resizable = 1 << 0, // Allow resizing columns.
ImGuiTableFlags_Reorderable = 1 << 1, // Allow reordering columns in header row (need calling TableSetupColumn() + TableHeadersRow() to display headers)
ImGuiTableFlags_Hideable = 1 << 2, // Allow hiding/disabling columns in context menu.
ImGuiTableFlags_Sortable = 1 << 3, // Allow sorting on one column (sort_specs_count will always be == 1). Call TableGetSortSpecs() to obtain sort specs.
ImGuiTableFlags_MultiSortable = 1 << 4, // Allow sorting on multiple columns by holding Shift (sort_specs_count may be > 1). Call TableGetSortSpecs() to obtain sort specs.
ImGuiTableFlags_NoSavedSettings = 1 << 5, // Disable persisting columns order, width and sort settings in the .ini file.
ImGuiTableFlags_ContextMenuInBody = 1 << 6, // Right-click on columns body/contents will display table context menu. By default it is available in TableHeadersRow().
ImGuiTableFlags_None = 0,
ImGuiTableFlags_Resizable = 1 << 0, // Enable resizing columns.
ImGuiTableFlags_Reorderable = 1 << 1, // Enable reordering columns in header row (need calling TableSetupColumn() + TableHeadersRow() to display headers)
ImGuiTableFlags_Hideable = 1 << 2, // Enable hiding/disabling columns in context menu.
ImGuiTableFlags_Sortable = 1 << 3, // Enable sorting. Call TableGetSortSpecs() to obtain sort specs. Also see ImGuiTableFlags_SortMulti and ImGuiTableFlags_SortTristate.
ImGuiTableFlags_NoSavedSettings = 1 << 4, // Disable persisting columns order, width and sort settings in the .ini file.
ImGuiTableFlags_ContextMenuInBody = 1 << 5, // Right-click on columns body/contents will display table context menu. By default it is available in TableHeadersRow().
// Decorations
ImGuiTableFlags_RowBg = 1 << 7, // Set each RowBg color with ImGuiCol_TableRowBg or ImGuiCol_TableRowBgAlt (equivalent of calling TableSetBgColor with ImGuiTableBgFlags_RowBg0 on each row manually)
ImGuiTableFlags_BordersInnerH = 1 << 8, // Draw horizontal borders between rows.
ImGuiTableFlags_BordersOuterH = 1 << 9, // Draw horizontal borders at the top and bottom.
ImGuiTableFlags_BordersInnerV = 1 << 10, // Draw vertical borders between columns.
ImGuiTableFlags_BordersOuterV = 1 << 11, // Draw vertical borders on the left and right sides.
ImGuiTableFlags_BordersH = ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_BordersOuterH, // Draw horizontal borders.
ImGuiTableFlags_BordersV = ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersOuterV, // Draw vertical borders.
ImGuiTableFlags_BordersInner = ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersInnerH, // Draw inner borders.
ImGuiTableFlags_BordersOuter = ImGuiTableFlags_BordersOuterV | ImGuiTableFlags_BordersOuterH, // Draw outer borders.
ImGuiTableFlags_Borders = ImGuiTableFlags_BordersInner | ImGuiTableFlags_BordersOuter, // Draw all borders.
ImGuiTableFlags_NoBordersInBody = 1 << 12, // Disable vertical borders in columns Body (borders will always appears in Headers).
ImGuiTableFlags_NoBordersInBodyUntilResize = 1 << 13, // Disable vertical borders in columns Body until hovered for resize (borders will always appears in Headers).
// Sizing
ImGuiTableFlags_ColumnsWidthStretch = 1 << 14, // Default if ScrollX is off. Columns will default to use _WidthStretch. Read description above for more details.
ImGuiTableFlags_ColumnsWidthFixed = 1 << 15, // Default if ScrollX is on. Columns will default to use _WidthFixed or _WidthAutoResize policy (if Resizable is off). Read description above for more details.
ImGuiTableFlags_SameWidths = 1 << 16, // Make all columns the same widths which is useful with Fixed columns policy (but granted by default with Stretch policy + no resize). Implicitly enable ImGuiTableFlags_NoKeepColumnsVisible and disable ImGuiTableFlags_Resizable.
ImGuiTableFlags_NoHeadersWidth = 1 << 17, // Disable headers' contribution to automatic width calculation.
ImGuiTableFlags_NoHostExtendY = 1 << 18, // Disable extending past the limit set by outer_size.y, only meaningful when neither of ScrollX|ScrollY are set (data below the limit will be clipped and not visible)
ImGuiTableFlags_NoKeepColumnsVisible = 1 << 19, // Disable keeping column always minimally visible when ScrollX is off and table gets too small.
ImGuiTableFlags_PreciseWidths = 1 << 20, // Disable distributing remainder width to stretched columns (width allocation on a 100-wide table with 3 columns: Without this flag: 33,33,34. With this flag: 33,33,33). With larger number of columns, resizing will appear to be less smooth.
ImGuiTableFlags_NoClip = 1 << 21, // Disable clipping rectangle for every individual columns (reduce draw command count, items will be able to overflow into other columns). Generally incompatible with TableSetupScrollFreeze().
ImGuiTableFlags_RowBg = 1 << 6, // Set each RowBg color with ImGuiCol_TableRowBg or ImGuiCol_TableRowBgAlt (equivalent of calling TableSetBgColor with ImGuiTableBgFlags_RowBg0 on each row manually)
ImGuiTableFlags_BordersInnerH = 1 << 7, // Draw horizontal borders between rows.
ImGuiTableFlags_BordersOuterH = 1 << 8, // Draw horizontal borders at the top and bottom.
ImGuiTableFlags_BordersInnerV = 1 << 9, // Draw vertical borders between columns.
ImGuiTableFlags_BordersOuterV = 1 << 10, // Draw vertical borders on the left and right sides.
ImGuiTableFlags_BordersH = ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_BordersOuterH, // Draw horizontal borders.
ImGuiTableFlags_BordersV = ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersOuterV, // Draw vertical borders.
ImGuiTableFlags_BordersInner = ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersInnerH, // Draw inner borders.
ImGuiTableFlags_BordersOuter = ImGuiTableFlags_BordersOuterV | ImGuiTableFlags_BordersOuterH, // Draw outer borders.
ImGuiTableFlags_Borders = ImGuiTableFlags_BordersInner | ImGuiTableFlags_BordersOuter, // Draw all borders.
ImGuiTableFlags_NoBordersInBody = 1 << 11, // [ALPHA] Disable vertical borders in columns Body (borders will always appears in Headers). -> May move to style
ImGuiTableFlags_NoBordersInBodyUntilResize = 1 << 12, // [ALPHA] Disable vertical borders in columns Body until hovered for resize (borders will always appears in Headers). -> May move to style
// Sizing Policy (read above for defaults)
ImGuiTableFlags_SizingFixedFit = 1 << 13, // Columns default to _WidthFixed or _WidthAuto (if resizable or not resizable), matching contents width.
ImGuiTableFlags_SizingFixedSame = 2 << 13, // Columns default to _WidthFixed or _WidthAuto (if resizable or not resizable), matching the maximum contents width of all columns. Implicitly enable ImGuiTableFlags_NoKeepColumnsVisible.
ImGuiTableFlags_SizingStretchProp = 3 << 13, // Columns default to _WidthStretch with default weights proportional to each columns contents widths.
ImGuiTableFlags_SizingStretchSame = 4 << 13, // Columns default to _WidthStretch with default weights all equal, unless overridden by TableSetupColumn().
// Sizing Extra Options
ImGuiTableFlags_NoHostExtendX = 1 << 16, // Make outer width auto-fit to columns, overriding outer_size.x value. Only available when ScrollX/ScrollY are disabled and Stretch columns are not used.
ImGuiTableFlags_NoHostExtendY = 1 << 17, // Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit). Only available when ScrollX/ScrollY are disabled. Data below the limit will be clipped and not visible.
ImGuiTableFlags_NoKeepColumnsVisible = 1 << 18, // Disable keeping column always minimally visible when ScrollX is off and table gets too small. Not recommended if columns are resizable.
ImGuiTableFlags_PreciseWidths = 1 << 19, // Disable distributing remainder width to stretched columns (width allocation on a 100-wide table with 3 columns: Without this flag: 33,33,34. With this flag: 33,33,33). With larger number of columns, resizing will appear to be less smooth.
// Clipping
ImGuiTableFlags_NoClip = 1 << 20, // Disable clipping rectangle for every individual columns (reduce draw command count, items will be able to overflow into other columns). Generally incompatible with TableSetupScrollFreeze().
// Padding
ImGuiTableFlags_PadOuterX = 1 << 22, // Default if BordersOuterV is on. Enable outer-most padding.
ImGuiTableFlags_NoPadOuterX = 1 << 23, // Default if BordersOuterV is off. Disable outer-most padding.
ImGuiTableFlags_NoPadInnerX = 1 << 24, // Disable inner padding between columns (double inner padding if BordersOuterV is on, single inner padding if BordersOuterV is off).
ImGuiTableFlags_PadOuterX = 1 << 21, // Default if BordersOuterV is on. Enable outer-most padding. Generally desirable if you have headers.
ImGuiTableFlags_NoPadOuterX = 1 << 22, // Default if BordersOuterV is off. Disable outer-most padding.
ImGuiTableFlags_NoPadInnerX = 1 << 23, // Disable inner padding between columns (double inner padding if BordersOuterV is on, single inner padding if BordersOuterV is off).
// Scrolling
ImGuiTableFlags_ScrollX = 1 << 25, // Enable horizontal scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size. Changes default sizing policy. Because this create a child window, ScrollY is currently generally recommended when using ScrollX.
ImGuiTableFlags_ScrollY = 1 << 26 // Enable vertical scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size.
ImGuiTableFlags_ScrollX = 1 << 24, // Enable horizontal scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size. Changes default sizing policy. Because this create a child window, ScrollY is currently generally recommended when using ScrollX.
ImGuiTableFlags_ScrollY = 1 << 25, // Enable vertical scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size.
// Sorting
ImGuiTableFlags_SortMulti = 1 << 26, // Hold shift when clicking headers to sort on multiple column. TableGetSortSpecs() may return specs where (SpecsCount > 1).
ImGuiTableFlags_SortTristate = 1 << 27, // Allow no sorting, disable default sorting. TableGetSortSpecs() may return specs where (SpecsCount == 0).
// [Internal] Combinations and masks
ImGuiTableFlags_SizingMask_ = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_SizingFixedSame | ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_SizingStretchSame
// Obsolete names (will be removed soon)
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
//, ImGuiTableFlags_ColumnsWidthFixed = ImGuiTableFlags_SizingFixedFit, ImGuiTableFlags_ColumnsWidthStretch = ImGuiTableFlags_SizingStretchSame // WIP Tables 2020/12
//, ImGuiTableFlags_SizingPolicyFixed = ImGuiTableFlags_SizingFixedFit, ImGuiTableFlags_SizingPolicyStretch = ImGuiTableFlags_SizingStretchSame // WIP Tables 2021/01
#endif
};
// Flags for ImGui::TableSetupColumn()
enum ImGuiTableColumnFlags_
{
// Input configuration flags
ImGuiTableColumnFlags_None = 0,
ImGuiTableColumnFlags_DefaultHide = 1 << 0, // Default as a hidden/disabled column.
ImGuiTableColumnFlags_DefaultSort = 1 << 1, // Default as a sorting column.
ImGuiTableColumnFlags_WidthStretch = 1 << 2, // Column will stretch. Preferable with horizontal scrolling disabled (default if table sizing policy is _ColumnsWidthStretch).
ImGuiTableColumnFlags_WidthFixed = 1 << 3, // Column will not stretch. Preferable with horizontal scrolling enabled (default if table sizing policy is _ColumnsWidthFixed and table is resizable).
ImGuiTableColumnFlags_WidthAutoResize = 1 << 4, // Column will not stretch and keep resizing based on submitted contents (default if table sizing policy is _ColumnsWidthFixed and table is not resizable).
ImGuiTableColumnFlags_NoResize = 1 << 5, // Disable manual resizing.
ImGuiTableColumnFlags_NoReorder = 1 << 6, // Disable manual reordering this column, this will also prevent other columns from crossing over this column.
ImGuiTableColumnFlags_NoHide = 1 << 7, // Disable ability to hide/disable this column.
ImGuiTableColumnFlags_NoClip = 1 << 8, // Disable clipping for this column (all NoClip columns will render in a same draw command).
ImGuiTableColumnFlags_NoSort = 1 << 9, // Disable ability to sort on this field (even if ImGuiTableFlags_Sortable is set on the table).
ImGuiTableColumnFlags_NoSortAscending = 1 << 10, // Disable ability to sort in the ascending direction.
ImGuiTableColumnFlags_NoSortDescending = 1 << 11, // Disable ability to sort in the descending direction.
ImGuiTableColumnFlags_NoHeaderWidth = 1 << 12, // Header width don't contribute to automatic column width.
ImGuiTableColumnFlags_PreferSortAscending = 1 << 13, // Make the initial sort direction Ascending when first sorting on this column (default).
ImGuiTableColumnFlags_PreferSortDescending = 1 << 14, // Make the initial sort direction Descending when first sorting on this column.
ImGuiTableColumnFlags_IndentEnable = 1 << 15, // Use current Indent value when entering cell (default for column 0).
ImGuiTableColumnFlags_IndentDisable = 1 << 16, // Ignore current Indent value when entering cell (default for columns > 0). Indentation changes _within_ the cell will still be honored.
ImGuiTableColumnFlags_None = 0,
ImGuiTableColumnFlags_DefaultHide = 1 << 0, // Default as a hidden/disabled column.
ImGuiTableColumnFlags_DefaultSort = 1 << 1, // Default as a sorting column.
ImGuiTableColumnFlags_WidthStretch = 1 << 2, // Column will stretch. Preferable with horizontal scrolling disabled (default if table sizing policy is _SizingStretchSame or _SizingStretchProp).
ImGuiTableColumnFlags_WidthFixed = 1 << 3, // Column will not stretch. Preferable with horizontal scrolling enabled (default if table sizing policy is _SizingFixedFit and table is resizable).
ImGuiTableColumnFlags_NoResize = 1 << 4, // Disable manual resizing.
ImGuiTableColumnFlags_NoReorder = 1 << 5, // Disable manual reordering this column, this will also prevent other columns from crossing over this column.
ImGuiTableColumnFlags_NoHide = 1 << 6, // Disable ability to hide/disable this column.
ImGuiTableColumnFlags_NoClip = 1 << 7, // Disable clipping for this column (all NoClip columns will render in a same draw command).
ImGuiTableColumnFlags_NoSort = 1 << 8, // Disable ability to sort on this field (even if ImGuiTableFlags_Sortable is set on the table).
ImGuiTableColumnFlags_NoSortAscending = 1 << 9, // Disable ability to sort in the ascending direction.
ImGuiTableColumnFlags_NoSortDescending = 1 << 10, // Disable ability to sort in the descending direction.
ImGuiTableColumnFlags_NoHeaderWidth = 1 << 11, // Disable header text width contribution to automatic column width.
ImGuiTableColumnFlags_PreferSortAscending = 1 << 12, // Make the initial sort direction Ascending when first sorting on this column (default).
ImGuiTableColumnFlags_PreferSortDescending = 1 << 13, // Make the initial sort direction Descending when first sorting on this column.
ImGuiTableColumnFlags_IndentEnable = 1 << 14, // Use current Indent value when entering cell (default for column 0).
ImGuiTableColumnFlags_IndentDisable = 1 << 15, // Ignore current Indent value when entering cell (default for columns > 0). Indentation changes _within_ the cell will still be honored.
// Output status flags, read-only via TableGetColumnFlags()
ImGuiTableColumnFlags_IsEnabled = 1 << 20, // Status: is enabled == not hidden by user/api (referred to as "Hide" in _DefaultHide and _NoHide) flags.
ImGuiTableColumnFlags_IsVisible = 1 << 21, // Status: is visible == is enabled AND not clipped by scrolling.
ImGuiTableColumnFlags_IsSorted = 1 << 22, // Status: is currently part of the sort specs
ImGuiTableColumnFlags_IsHovered = 1 << 23, // Status: is hovered by mouse
ImGuiTableColumnFlags_IsEnabled = 1 << 20, // Status: is enabled == not hidden by user/api (referred to as "Hide" in _DefaultHide and _NoHide) flags.
ImGuiTableColumnFlags_IsVisible = 1 << 21, // Status: is visible == is enabled AND not clipped by scrolling.
ImGuiTableColumnFlags_IsSorted = 1 << 22, // Status: is currently part of the sort specs
ImGuiTableColumnFlags_IsHovered = 1 << 23, // Status: is hovered by mouse
// [Internal] Combinations and masks
ImGuiTableColumnFlags_WidthMask_ = ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthAutoResize,
ImGuiTableColumnFlags_IndentMask_ = ImGuiTableColumnFlags_IndentEnable | ImGuiTableColumnFlags_IndentDisable,
ImGuiTableColumnFlags_StatusMask_ = ImGuiTableColumnFlags_IsEnabled | ImGuiTableColumnFlags_IsVisible | ImGuiTableColumnFlags_IsSorted | ImGuiTableColumnFlags_IsHovered,
ImGuiTableColumnFlags_NoDirectResize_ = 1 << 30 // [Internal] Disable user resizing this column directly (it may however we resized indirectly from its left edge)
ImGuiTableColumnFlags_WidthMask_ = ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_WidthFixed,
ImGuiTableColumnFlags_IndentMask_ = ImGuiTableColumnFlags_IndentEnable | ImGuiTableColumnFlags_IndentDisable,
ImGuiTableColumnFlags_StatusMask_ = ImGuiTableColumnFlags_IsEnabled | ImGuiTableColumnFlags_IsVisible | ImGuiTableColumnFlags_IsSorted | ImGuiTableColumnFlags_IsHovered,
ImGuiTableColumnFlags_NoDirectResize_ = 1 << 30 // [Internal] Disable user resizing this column directly (it may however we resized indirectly from its left edge)
// Obsolete names (will be removed soon)
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
//ImGuiTableColumnFlags_WidthAuto = ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoResize, // Column will not stretch and keep resizing based on submitted contents.
#endif
};
// Flags for ImGui::TableNextRow()
@ -1146,11 +1186,9 @@ enum ImGuiTableRowFlags_
enum ImGuiTableBgTarget_
{
ImGuiTableBgTarget_None = 0,
//ImGuiTableBgTarget_ColumnBg0 = 1, // FIXME-TABLE: Todo. Set column background color 0 (generally used for background
//ImGuiTableBgTarget_ColumnBg1 = 2, // FIXME-TABLE: Todo. Set column background color 1 (generally used for selection marking)
ImGuiTableBgTarget_RowBg0 = 3, // Set row background color 0 (generally used for background, automatically set when ImGuiTableFlags_RowBg is used)
ImGuiTableBgTarget_RowBg1 = 4, // Set row background color 1 (generally used for selection marking)
ImGuiTableBgTarget_CellBg = 5 // Set cell background color (top-most color)
ImGuiTableBgTarget_RowBg0 = 1, // Set row background color 0 (generally used for background, automatically set when ImGuiTableFlags_RowBg is used)
ImGuiTableBgTarget_RowBg1 = 2, // Set row background color 1 (generally used for selection marking)
ImGuiTableBgTarget_CellBg = 3 // Set cell background color (top-most color)
};
// Flags for ImGui::IsWindowFocused()
@ -1279,7 +1317,7 @@ enum ImGuiKeyModFlags_
// Gamepad/Keyboard navigation
// Keyboard: Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.KeysDown[] + io.KeyMap[] arrays.
// Gamepad: Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad to enable. Backend: set ImGuiBackendFlags_HasGamepad and fill the io.NavInputs[] fields before calling NewFrame(). Note that io.NavInputs[] is cleared by EndFrame().
// Read instructions in imgui.cpp for more details. Download PNG/PSD at http://goo.gl/9LgVZW.
// Read instructions in imgui.cpp for more details. Download PNG/PSD at http://dearimgui.org/controls_sheets.
enum ImGuiNavInput_
{
// Gamepad Mapping
@ -1394,11 +1432,6 @@ enum ImGuiCol_
ImGuiCol_NavWindowingDimBg, // Darken/colorize entire screen behind the CTRL+TAB window list, when active
ImGuiCol_ModalWindowDimBg, // Darken/colorize entire screen behind a modal window, when one is active
ImGuiCol_COUNT
// Obsolete names (will be removed)
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
, ImGuiCol_ModalWindowDarkening = ImGuiCol_ModalWindowDimBg // [renamed in 1.63]
#endif
};
// Enumeration for PushStyleVar() / PopStyleVar() to temporarily modify the ImGuiStyle structure.
@ -1554,7 +1587,10 @@ enum ImGuiCond_
};
//-----------------------------------------------------------------------------
// Helpers: Memory allocations macros
// [SECTION] Helpers: Memory allocations macros, ImVector<>
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// IM_MALLOC(), IM_FREE(), IM_NEW(), IM_PLACEMENT_NEW(), IM_DELETE()
// We call C++ constructor on own allocated memory via the placement "new(ptr) Type()" syntax.
// Defining a custom placement new() with a custom parameter allows us to bypass including <new> which on some platforms complains when user has disabled exceptions.
@ -1570,7 +1606,7 @@ inline void operator delete(void*, ImNewWrapper, void*) {} // This is only re
template<typename T> void IM_DELETE(T* p) { if (p) { p->~T(); ImGui::MemFree(p); } }
//-----------------------------------------------------------------------------
// Helper: ImVector<>
// ImVector<>
// Lightweight std::vector<>-like class to avoid dragging dependencies (also, some implementations of STL with debug enabled are absurdly slow, we bypass it so our code runs fast in debug).
//-----------------------------------------------------------------------------
// - You generally do NOT need to care or use this ever. But we need to make it available in imgui.h because some of our public structures are relying on it.
@ -1640,7 +1676,8 @@ struct ImVector
};
//-----------------------------------------------------------------------------
// ImGuiStyle
// [SECTION] ImGuiStyle
//-----------------------------------------------------------------------------
// You may modify the ImGui::GetStyle() main instance during initialization and before NewFrame().
// During the frame, use ImGui::PushStyleVar(ImGuiStyleVar_XXXX)/PopStyleVar() to alter the main style values,
// and ImGui::PushStyleColor(ImGuiCol_XXX)/PopStyleColor() for colors.
@ -1694,7 +1731,8 @@ struct ImGuiStyle
};
//-----------------------------------------------------------------------------
// ImGuiIO
// [SECTION] ImGuiIO
//-----------------------------------------------------------------------------
// Communicate most settings and inputs/outputs to Dear ImGui using this structure.
// Access via ImGui::GetIO(). Read 'Programmer guide' section in .cpp file for general usage.
//-----------------------------------------------------------------------------
@ -1707,7 +1745,7 @@ struct ImGuiIO
ImGuiConfigFlags ConfigFlags; // = 0 // See ImGuiConfigFlags_ enum. Set by user/application. Gamepad/keyboard navigation options, etc.
ImGuiBackendFlags BackendFlags; // = 0 // See ImGuiBackendFlags_ enum. Set by backend (imgui_impl_xxx files or custom backend) to communicate features supported by the backend.
ImVec2 DisplaySize; // <unset> // Main display size, in pixels.
ImVec2 DisplaySize; // <unset> // Main display size, in pixels (generally == GetMainViewport()->Size)
float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds.
float IniSavingRate; // = 5.0f // Minimum time between saving positions/sizes to .ini file, in seconds.
const char* IniFilename; // = "imgui.ini" // Path to .ini file. Set NULL to disable automatic .ini loading/saving, if e.g. you want to manually load/save from memory.
@ -1728,11 +1766,12 @@ struct ImGuiIO
// Miscellaneous options
bool MouseDrawCursor; // = false // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). Cannot be easily renamed to 'io.ConfigXXX' because this is frequently used by backend implementations.
bool ConfigMacOSXBehaviors; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl (was called io.OptMacOSXBehaviors prior to 1.63)
bool ConfigInputTextCursorBlink; // = true // Set to false to disable blinking cursor, for users who consider it distracting. (was called: io.OptCursorBlink prior to 1.63)
bool ConfigMacOSXBehaviors; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl.
bool ConfigInputTextCursorBlink; // = true // Enable blinking cursor (optional as some users consider it to be distracting).
bool ConfigDragClickToInputText; // = false // [BETA] Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving). Not desirable on devices without a keyboard.
bool ConfigWindowsResizeFromEdges; // = true // Enable resizing of windows from their edges and from the lower-left corner. This requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback. (This used to be a per-window ImGuiWindowFlags_ResizeFromAnySide flag)
bool ConfigWindowsMoveFromTitleBarOnly; // = false // [BETA] Set to true to only allow moving windows when clicked+dragged from the title bar. Windows without a title bar are not affected.
float ConfigMemoryCompactTimer; // = 60.0f // [BETA] Free transient windows/tables memory buffers when unused for given amount of time. Set to -1.0f to disable.
bool ConfigWindowsMoveFromTitleBarOnly; // = false // Enable allowing to move windows only when clicking on their title bar. Does not apply to windows without a title bar.
float ConfigMemoryCompactTimer; // = 60.0f // Timer (in seconds) to free transient windows/tables memory buffers when unused. Set to -1.0f to disable.
//------------------------------------------------------------------
// Platform Functions
@ -1828,7 +1867,7 @@ struct ImGuiIO
};
//-----------------------------------------------------------------------------
// Misc data structures
// [SECTION] Misc data structures
//-----------------------------------------------------------------------------
// Shared state of InputText(), passed as an argument to your callback when a ImGuiInputTextFlags_Callback* flag is used.
@ -1919,20 +1958,25 @@ struct ImGuiTableColumnSortSpecs
struct ImGuiTableSortSpecs
{
const ImGuiTableColumnSortSpecs* Specs; // Pointer to sort spec array.
int SpecsCount; // Sort spec count. Most often 1 unless e.g. ImGuiTableFlags_MultiSortable is enabled.
int SpecsCount; // Sort spec count. Most often 1. May be > 1 when ImGuiTableFlags_SortMulti is enabled. May be == 0 when ImGuiTableFlags_SortTristate is enabled.
bool SpecsDirty; // Set to true when specs have changed since last time! Use this to sort again, then clear the flag.
ImGuiTableSortSpecs() { memset(this, 0, sizeof(*this)); }
};
//-----------------------------------------------------------------------------
// Obsolete functions (Will be removed! Read 'API BREAKING CHANGES' section in imgui.cpp for details)
// [SECTION] Obsolete functions
// (Will be removed! Read 'API BREAKING CHANGES' section in imgui.cpp for details)
// Please keep your copy of dear imgui up to date! Occasionally set '#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS' in imconfig.h to stay ahead.
//-----------------------------------------------------------------------------
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
namespace ImGui
{
// OBSOLETED in 1.81 (from February 2021)
IMGUI_API bool ListBoxHeader(const char* label, int items_count, int height_in_items = -1); // Helper to calculate size from items_count and height_in_items
static inline bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0, 0)) { return BeginListBox(label, size); }
static inline void ListBoxFooter() { EndListBox(); }
// OBSOLETED in 1.79 (from August 2020)
static inline void OpenPopupContextItem(const char* str_id = NULL, ImGuiMouseButton mb = 1) { OpenPopupOnItemClick(str_id, mb); } // Bool return value removed. Use IsWindowAppearing() in BeginPopup() instead. Renamed in 1.77, renamed back in 1.79. Sorry!
// OBSOLETED in 1.78 (from June 2020)
@ -1962,15 +2006,11 @@ namespace ImGui
static inline ImDrawList* GetOverlayDrawList() { return GetForegroundDrawList(); }
// OBSOLETED in 1.66 (from Sep 2018)
static inline void SetScrollHere(float center_ratio=0.5f){ SetScrollHereY(center_ratio); }
// OBSOLETED in 1.63 (between Aug 2018 and Sept 2018)
static inline bool IsItemDeactivatedAfterChange() { return IsItemDeactivatedAfterEdit(); }
}
typedef ImGuiInputTextCallback ImGuiTextEditCallback; // OBSOLETED in 1.63 (from Aug 2018): made the names consistent
typedef ImGuiInputTextCallbackData ImGuiTextEditCallbackData;
#endif
//-----------------------------------------------------------------------------
// Helpers
// [SECTION] Helpers (ImGuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, ImColor)
//-----------------------------------------------------------------------------
// Helper: Unicode defines
@ -2172,7 +2212,7 @@ struct ImColor
};
//-----------------------------------------------------------------------------
// Draw List API (ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawListFlags, ImDrawList, ImDrawData)
// [SECTION] Drawing API (ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawListFlags, ImDrawList, ImDrawData)
// Hold a series of drawing commands. The user provides a renderer for ImDrawData which essentially contains an array of ImDrawList.
//-----------------------------------------------------------------------------
@ -2303,7 +2343,8 @@ enum ImDrawListFlags_
// Each dear imgui window contains its own ImDrawList. You can use ImGui::GetWindowDrawList() to
// access the current window draw list and draw custom primitives.
// You can interleave normal ImGui:: calls and adding primitives to the current draw list.
// All positions are generally in pixel coordinates (top-left at (0,0), bottom-right at io.DisplaySize), but you are totally free to apply whatever transformation matrix to want to the data (if you apply such transformation you'll want to apply it to ClipRect as well)
// In single viewport mode, top-left is == GetMainViewport()->Pos (generally 0,0), bottom-right is == GetMainViewport()->Pos+Size (generally io.DisplaySize).
// You are totally free to apply whatever transformation matrix to want to the data (depending on the use of the transformation you may want to apply it to ClipRect as well!)
// Important: Primitives are always added to the list and not culled (culling is done at higher-level by ImGui:: functions), if you use this API a lot consider coarse culling your drawn objects.
struct ImDrawList
{
@ -2324,6 +2365,7 @@ struct ImDrawList
ImVector<ImVec2> _Path; // [Internal] current path building
ImDrawCmdHeader _CmdHeader; // [Internal] template of active commands. Fields should match those of CmdBuffer.back().
ImDrawListSplitter _Splitter; // [Internal] for channels api (note: prefer using your own persistent instance of ImDrawListSplitter!)
float _FringeScale; // [Internal] anti-alias fringe is scaled by this value, this helps to keep things sharp while zooming at vertex buffer content
// If you want to create ImDrawList instances, pass them ImGui::GetDrawListSharedData() or create and use your own ImDrawListSharedData (so you can use ImDrawList without ImGui)
ImDrawList(const ImDrawListSharedData* shared_data) { memset(this, 0, sizeof(*this)); _Data = shared_data; }
@ -2359,7 +2401,8 @@ struct ImDrawList
IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL);
IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, bool closed, float thickness);
IMGUI_API void AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col); // Note: Anti-aliased filling requires points to be in clockwise order.
IMGUI_API void AddBezierCurve(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0);
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)
// Image primitives
// - Read FAQ to understand what ImTextureID is.
@ -2376,8 +2419,9 @@ struct ImDrawList
inline void PathFillConvex(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col); _Path.Size = 0; } // Note: Anti-aliased filling requires points to be in clockwise order.
inline void PathStroke(ImU32 col, bool closed, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, closed, thickness); _Path.Size = 0; }
IMGUI_API void PathArcTo(const ImVec2& center, float radius, float a_min, float a_max, int num_segments = 10);
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 PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, 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 PathBezierCubicCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments = 0); // Cubic Bezier (4 control points)
IMGUI_API void PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3, int num_segments = 0); // Quadratic Bezier (3 control points)
IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, ImDrawCornerFlags rounding_corners = ImDrawCornerFlags_All);
// Advanced
@ -2407,6 +2451,11 @@ struct ImDrawList
inline void PrimWriteIdx(ImDrawIdx idx) { *_IdxWritePtr = idx; _IdxWritePtr++; }
inline void PrimVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) { PrimWriteIdx((ImDrawIdx)_VtxCurrentIdx); PrimWriteVtx(pos, uv, col); } // Write vertex with unique index
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
inline void AddBezierCurve(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0) { AddBezierCubic(p1, p2, p3, p4, col, thickness, num_segments); }
inline void PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments = 0) { PathBezierCubicCurveTo(p2, p3, p4, num_segments); }
#endif
// [Internal helpers]
IMGUI_API void _ResetForNewFrame();
IMGUI_API void _ClearFreeMemory();
@ -2422,24 +2471,23 @@ struct ImDrawList
struct ImDrawData
{
bool Valid; // Only valid after Render() is called and before the next NewFrame() is called.
ImDrawList** CmdLists; // Array of ImDrawList* to render. The ImDrawList are owned by ImGuiContext and only pointed to from here.
int CmdListsCount; // Number of ImDrawList* to render
int TotalIdxCount; // For convenience, sum of all ImDrawList's IdxBuffer.Size
int TotalVtxCount; // For convenience, sum of all ImDrawList's VtxBuffer.Size
ImVec2 DisplayPos; // Upper-left position of the viewport to render (== upper-left of the orthogonal projection matrix to use)
ImVec2 DisplaySize; // Size of the viewport to render (== io.DisplaySize for the main viewport) (DisplayPos + DisplaySize == lower-right of the orthogonal projection matrix to use)
ImDrawList** CmdLists; // Array of ImDrawList* to render. The ImDrawList are owned by ImGuiContext and only pointed to from here.
ImVec2 DisplayPos; // Top-left position of the viewport to render (== top-left of the orthogonal projection matrix to use) (== GetMainViewport()->Pos for the main viewport, == (0.0) in most single-viewport applications)
ImVec2 DisplaySize; // Size of the viewport to render (== GetMainViewport()->Size for the main viewport, == io.DisplaySize in most single-viewport applications)
ImVec2 FramebufferScale; // Amount of pixels for each unit of DisplaySize. Based on io.DisplayFramebufferScale. Generally (1,1) on normal display, (2,2) on OSX with Retina display.
// Functions
ImDrawData() { Valid = false; Clear(); }
~ImDrawData() { Clear(); }
void Clear() { Valid = false; CmdLists = NULL; CmdListsCount = TotalVtxCount = TotalIdxCount = 0; DisplayPos = DisplaySize = FramebufferScale = ImVec2(0.f, 0.f); } // The ImDrawList are owned by ImGuiContext!
ImDrawData() { Clear(); }
void Clear() { memset(this, 0, sizeof(*this)); } // The ImDrawList are owned by ImGuiContext!
IMGUI_API void DeIndexAllBuffers(); // Helper to convert all buffers from indexed to non-indexed, in case you cannot render indexed. Note: this is slow and most likely a waste of resources. Always prefer indexed rendering!
IMGUI_API void ScaleClipRects(const ImVec2& fb_scale); // Helper to scale the ClipRect field of each ImDrawCmd. Use if your final output buffer is at a different scale than Dear ImGui expects, or if there is a difference between your window resolution and framebuffer resolution.
};
//-----------------------------------------------------------------------------
// Font API (ImFontConfig, ImFontGlyph, ImFontAtlasFlags, ImFontAtlas, ImFontGlyphRangesBuilder, ImFont)
// [SECTION] Font API (ImFontConfig, ImFontGlyph, ImFontAtlasFlags, ImFontAtlas, ImFontGlyphRangesBuilder, ImFont)
//-----------------------------------------------------------------------------
struct ImFontConfig
@ -2449,8 +2497,8 @@ struct ImFontConfig
bool FontDataOwnedByAtlas; // true // TTF/OTF data ownership taken by the container ImFontAtlas (will delete memory itself).
int FontNo; // 0 // Index of font within TTF/OTF file
float SizePixels; // // Size in pixels for rasterizer (more or less maps to the resulting font height).
int OversampleH; // 3 // Rasterize at higher quality for sub-pixel positioning. Read https://github.com/nothings/stb/blob/master/tests/oversample/README.md for details.
int OversampleV; // 1 // Rasterize at higher quality for sub-pixel positioning. We don't use sub-pixel positions on the Y axis.
int OversampleH; // 3 // Rasterize at higher quality for sub-pixel positioning. Note the difference between 2 and 3 is minimal so you can reduce this to 2 to save memory. Read https://github.com/nothings/stb/blob/master/tests/oversample/README.md for details.
int OversampleV; // 1 // Rasterize at higher quality for sub-pixel positioning. This is not really useful as we don't use sub-pixel positions on the Y axis.
bool PixelSnapH; // false // Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1.
ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs. Only X axis is supported for now.
ImVec2 GlyphOffset; // 0, 0 // Offset all glyphs from this font input.
@ -2458,7 +2506,7 @@ struct ImFontConfig
float GlyphMinAdvanceX; // 0 // Minimum AdvanceX for glyphs, set Min to align font icons, set both Min/Max to enforce mono-space font
float GlyphMaxAdvanceX; // FLT_MAX // Maximum AdvanceX for glyphs
bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights.
unsigned int RasterizerFlags; // 0x00 // Settings for custom font rasterizer (e.g. ImGuiFreeType). Leave as zero if you aren't using one.
unsigned int FontBuilderFlags; // 0 // Settings for custom font builder. THIS IS BUILDER IMPLEMENTATION DEPENDENT. Leave as zero if unsure.
float RasterizerMultiply; // 1.0f // Brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable.
ImWchar EllipsisChar; // -1 // Explicitly specify unicode codepoint of ellipsis character. When fonts are being merged first specified ellipsis will be used.
@ -2473,8 +2521,9 @@ struct ImFontConfig
// (Note: some language parsers may fail to convert the 31+1 bitfield members, in this case maybe drop store a single u32 or we can rework this)
struct ImFontGlyph
{
unsigned int Codepoint : 31; // 0x0000..0xFFFF
unsigned int Visible : 1; // Flag to allow early out when rendering
unsigned int Colored : 1; // Flag to indicate glyph is colored and should generally ignore tinting (make it usable with no shift on little-endian as this is used in loops)
unsigned int Visible : 1; // Flag to indicate glyph has no visible pixels (e.g. space). Allow early out when rendering.
unsigned int Codepoint : 30; // 0x0000..0x10FFFF
float AdvanceX; // Distance to next character (= data from font + ImFontConfig::GlyphExtraSpacing.x baked in)
float X0, Y0, X1, Y1; // Glyph corners
float U0, V0, U1, V1; // Texture coordinates
@ -2618,6 +2667,10 @@ struct ImFontAtlas
ImVector<ImFontConfig> ConfigData; // Configuration data
ImVec4 TexUvLines[IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 1]; // UVs for baked anti-aliased lines
// [Internal] Font builder
const ImFontBuilderIO* FontBuilderIO; // Opaque interface to a font builder (default to stb_truetype, can be changed to use FreeType by defining IMGUI_ENABLE_FREETYPE).
unsigned int FontBuilderFlags; // Shared flags (for all fonts) for custom font builder. THIS IS BUILD IMPLEMENTATION DEPENDENT. Per-font override is also available in ImFontConfig.
// [Internal] Packing data
int PackIdMouseCursors; // Custom texture rectangle ID for white pixel and mouse cursors
int PackIdLines; // Custom texture rectangle ID for baked anti-aliased lines
@ -2681,6 +2734,43 @@ struct ImFont
IMGUI_API bool IsGlyphRangeUnused(unsigned int c_begin, unsigned int c_last);
};
//-----------------------------------------------------------------------------
// [SECTION] Viewports
//-----------------------------------------------------------------------------
// Flags stored in ImGuiViewport::Flags
enum ImGuiViewportFlags_
{
ImGuiViewportFlags_None = 0,
ImGuiViewportFlags_IsPlatformWindow = 1 << 0, // Represent a Platform Window
ImGuiViewportFlags_IsPlatformMonitor = 1 << 1, // Represent a Platform Monitor (unused yet)
ImGuiViewportFlags_OwnedByApp = 1 << 2 // Platform Window: is created/managed by the application (rather than a dear imgui backend)
};
// - Currently represents the Platform Window created by the application which is hosting our Dear ImGui windows.
// - In 'docking' branch with multi-viewport enabled, we extend this concept to have multiple active viewports.
// - In the future we will extend this concept further to also represent Platform Monitor and support a "no main platform window" operation mode.
// - About Main Area vs Work Area:
// - Main Area = entire viewport.
// - Work Area = entire viewport minus sections used by main menu bars (for platform windows), or by task bar (for platform monitor).
// - Windows are generally trying to stay within the Work Area of their host viewport.
struct ImGuiViewport
{
ImGuiViewportFlags Flags; // See ImGuiViewportFlags_
ImVec2 Pos; // Main Area: Position of the viewport (Dear Imgui coordinates are the same as OS desktop/native coordinates)
ImVec2 Size; // Main Area: Size of the viewport.
ImVec2 WorkPos; // Work Area: Position of the viewport minus task bars, menus bars, status bars (>= Pos)
ImVec2 WorkSize; // Work Area: Size of the viewport minus task bars, menu bars, status bars (<= Size)
ImGuiViewport() { memset(this, 0, sizeof(*this)); }
// Helpers
ImVec2 GetCenter() const { return ImVec2(Pos.x + Size.x * 0.5f, Pos.y + Size.y * 0.5f); }
ImVec2 GetWorkCenter() const { return ImVec2(WorkPos.x + WorkSize.x * 0.5f, WorkPos.y + WorkSize.y * 0.5f); }
};
//-----------------------------------------------------------------------------
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
// dear imgui, v1.80 WIP
// dear imgui, v1.81
// (drawing and font code)
/*
@ -32,7 +32,11 @@ Index of this file:
#ifndef IMGUI_DEFINE_MATH_OPERATORS
#define IMGUI_DEFINE_MATH_OPERATORS
#endif
#include "imgui_internal.h"
#ifdef IMGUI_ENABLE_FREETYPE
#include "misc/freetype/imgui_freetype.h"
#endif
#include <stdio.h> // vsnprintf, sscanf, printf
#if !defined(alloca)
@ -118,7 +122,7 @@ namespace IMGUI_STB_NAMESPACE
#endif
#ifndef STB_RECT_PACK_IMPLEMENTATION // in case the user already have an implementation in the _same_ compilation unit (e.g. unity builds)
#ifndef IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
#ifndef IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION // in case the user already have an implementation in another compilation unit
#define STBRP_STATIC
#define STBRP_ASSERT(x) do { IM_ASSERT(x); } while (0)
#define STBRP_SORT ImQsort
@ -131,8 +135,9 @@ namespace IMGUI_STB_NAMESPACE
#endif
#endif
#ifdef IMGUI_ENABLE_STB_TRUETYPE
#ifndef STB_TRUETYPE_IMPLEMENTATION // in case the user already have an implementation in the _same_ compilation unit (e.g. unity builds)
#ifndef IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
#ifndef IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION // in case the user already have an implementation in another compilation unit
#define STBTT_malloc(x,u) ((void)(u), IM_ALLOC(x))
#define STBTT_free(x,u) ((void)(u), IM_FREE(x))
#define STBTT_assert(x) do { IM_ASSERT(x); } while(0)
@ -153,6 +158,7 @@ namespace IMGUI_STB_NAMESPACE
#include "imstb_truetype.h"
#endif
#endif
#endif // IMGUI_ENABLE_STB_TRUETYPE
#if defined(__GNUC__)
#pragma GCC diagnostic pop
@ -210,7 +216,7 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst)
colors[ImGuiCol_Separator] = colors[ImGuiCol_Border];
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.10f, 0.40f, 0.75f, 0.78f);
colors[ImGuiCol_SeparatorActive] = ImVec4(0.10f, 0.40f, 0.75f, 1.00f);
colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0.25f);
colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0.20f);
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f);
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f);
colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.80f);
@ -242,7 +248,7 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst)
colors[ImGuiCol_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f);
colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f);
colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.70f);
colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.85f);
colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
colors[ImGuiCol_PopupBg] = ImVec4(0.11f, 0.11f, 0.14f, 0.92f);
colors[ImGuiCol_Border] = ImVec4(0.50f, 0.50f, 0.50f, 0.50f);
@ -270,7 +276,7 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst)
colors[ImGuiCol_Separator] = ImVec4(0.50f, 0.50f, 0.50f, 0.60f);
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.60f, 0.60f, 0.70f, 1.00f);
colors[ImGuiCol_SeparatorActive] = ImVec4(0.70f, 0.70f, 0.90f, 1.00f);
colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.16f);
colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.10f);
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.78f, 0.82f, 1.00f, 0.60f);
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.78f, 0.82f, 1.00f, 0.90f);
colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.80f);
@ -331,7 +337,7 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
colors[ImGuiCol_Separator] = ImVec4(0.39f, 0.39f, 0.39f, 0.62f);
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.14f, 0.44f, 0.80f, 0.78f);
colors[ImGuiCol_SeparatorActive] = ImVec4(0.14f, 0.44f, 0.80f, 1.00f);
colors[ImGuiCol_ResizeGrip] = ImVec4(0.80f, 0.80f, 0.80f, 0.56f);
colors[ImGuiCol_ResizeGrip] = ImVec4(0.35f, 0.35f, 0.35f, 0.17f);
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f);
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f);
colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.90f);
@ -377,8 +383,8 @@ void ImDrawListSharedData::SetCircleSegmentMaxError(float max_error)
CircleSegmentMaxError = max_error;
for (int i = 0; i < IM_ARRAYSIZE(CircleSegmentCounts); i++)
{
const float radius = i + 1.0f;
const int segment_count = IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, CircleSegmentMaxError);
const float radius = (float)i;
const int segment_count = (i > 0) ? IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, CircleSegmentMaxError) : 0;
CircleSegmentCounts[i] = (ImU8)ImMin(segment_count, 255);
}
}
@ -405,6 +411,7 @@ void ImDrawList::_ResetForNewFrame()
_Path.resize(0);
_Splitter.Clear();
CmdBuffer.push_back(ImDrawCmd());
_FringeScale = 1.0f;
}
void ImDrawList::_ClearFreeMemory()
@ -680,12 +687,12 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
const ImVec2 opaque_uv = _Data->TexUvWhitePixel;
const int count = closed ? points_count : points_count - 1; // The number of line segments we need to draw
const bool thick_line = (thickness > 1.0f);
const bool thick_line = (thickness > _FringeScale);
if (Flags & ImDrawListFlags_AntiAliasedLines)
{
// Anti-aliased stroke
const float AA_SIZE = 1.0f;
const float AA_SIZE = _FringeScale;
const ImU32 col_trans = col & ~IM_COL32_A_MASK;
// Thicknesses <1.0 should behave like thickness 1.0
@ -696,7 +703,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
// Do we want to draw this line using a texture?
// - For now, only draw integer-width lines using textures to avoid issues with the way scaling occurs, could be improved.
// - If AA_SIZE is not 1.0f we cannot use the texture path.
const bool use_texture = (Flags & ImDrawListFlags_AntiAliasedLinesUseTex) && (integer_thickness < IM_DRAWLIST_TEX_LINES_WIDTH_MAX) && (fractional_thickness <= 0.00001f);
const bool use_texture = (Flags & ImDrawListFlags_AntiAliasedLinesUseTex) && (integer_thickness < IM_DRAWLIST_TEX_LINES_WIDTH_MAX) && (fractional_thickness <= 0.00001f) && (AA_SIZE == 1.0f);
// We should never hit this, because NewFrame() doesn't set ImDrawListFlags_AntiAliasedLinesUseTex unless ImFontAtlasFlags_NoBakedLines is off
IM_ASSERT_PARANOID(!use_texture || !(_Data->Font->ContainerAtlas->Flags & ImFontAtlasFlags_NoBakedLines));
@ -938,7 +945,7 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun
if (Flags & ImDrawListFlags_AntiAliasedFill)
{
// Anti-aliased Fill
const float AA_SIZE = 1.0f;
const float AA_SIZE = _FringeScale;
const ImU32 col_trans = col & ~IM_COL32_A_MASK;
const int idx_count = (points_count - 2)*3 + points_count * 6;
const int vtx_count = (points_count * 2);
@ -1011,11 +1018,12 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun
void ImDrawList::PathArcToFast(const ImVec2& center, float radius, int a_min_of_12, int a_max_of_12)
{
if (radius == 0.0f || a_min_of_12 > a_max_of_12)
if (radius == 0.0f)
{
_Path.push_back(center);
return;
}
IM_ASSERT(a_min_of_12 <= a_max_of_12);
// For legacy reason the PathArcToFast() always takes angles where 2*PI is represented by 12,
// but it is possible to set IM_DRAWLIST_ARCFAST_TESSELATION_MULTIPLIER to a higher value. This should compile to a no-op otherwise.
@ -1039,6 +1047,7 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa
_Path.push_back(center);
return;
}
IM_ASSERT(a_min <= a_max);
// Note that we are adding a point at both a_min and a_max.
// If you are trying to draw a full closed circle you don't want the overlapping points!
@ -1050,23 +1059,32 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa
}
}
ImVec2 ImBezierCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t)
ImVec2 ImBezierCubicCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t)
{
float u = 1.0f - t;
float w1 = u*u*u;
float w2 = 3*u*u*t;
float w3 = 3*u*t*t;
float w4 = t*t*t;
return ImVec2(w1*p1.x + w2*p2.x + w3*p3.x + w4*p4.x, w1*p1.y + w2*p2.y + w3*p3.y + w4*p4.y);
float w1 = u * u * u;
float w2 = 3 * u * u * t;
float w3 = 3 * u * t * t;
float w4 = t * t * t;
return ImVec2(w1 * p1.x + w2 * p2.x + w3 * p3.x + w4 * p4.x, w1 * p1.y + w2 * p2.y + w3 * p3.y + w4 * p4.y);
}
// Closely mimics BezierClosestPointCasteljauStep() in imgui.cpp
static void PathBezierToCasteljau(ImVector<ImVec2>* path, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float tess_tol, int level)
ImVec2 ImBezierQuadraticCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, float t)
{
float u = 1.0f - t;
float w1 = u * u;
float w2 = 2 * u * t;
float w3 = t * t;
return ImVec2(w1 * p1.x + w2 * p2.x + w3 * p3.x, w1 * p1.y + w2 * p2.y + w3 * p3.y);
}
// Closely mimics ImBezierCubicClosestPointCasteljau() in imgui.cpp
static void PathBezierCubicCurveToCasteljau(ImVector<ImVec2>* path, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float tess_tol, int level)
{
float dx = x4 - x1;
float dy = y4 - y1;
float d2 = ((x2 - x4) * dy - (y2 - y4) * dx);
float d3 = ((x3 - x4) * dy - (y3 - y4) * dx);
float d2 = (x2 - x4) * dy - (y2 - y4) * dx;
float d3 = (x3 - x4) * dy - (y3 - y4) * dx;
d2 = (d2 >= 0) ? d2 : -d2;
d3 = (d3 >= 0) ? d3 : -d3;
if ((d2 + d3) * (d2 + d3) < tess_tol * (dx * dx + dy * dy))
@ -1075,29 +1093,62 @@ static void PathBezierToCasteljau(ImVector<ImVec2>* path, float x1, float y1, fl
}
else if (level < 10)
{
float x12 = (x1 + x2)*0.5f, y12 = (y1 + y2)*0.5f;
float x23 = (x2 + x3)*0.5f, y23 = (y2 + y3)*0.5f;
float x34 = (x3 + x4)*0.5f, y34 = (y3 + y4)*0.5f;
float x123 = (x12 + x23)*0.5f, y123 = (y12 + y23)*0.5f;
float x234 = (x23 + x34)*0.5f, y234 = (y23 + y34)*0.5f;
float x1234 = (x123 + x234)*0.5f, y1234 = (y123 + y234)*0.5f;
PathBezierToCasteljau(path, x1, y1, x12, y12, x123, y123, x1234, y1234, tess_tol, level + 1);
PathBezierToCasteljau(path, x1234, y1234, x234, y234, x34, y34, x4, y4, tess_tol, level + 1);
float x12 = (x1 + x2) * 0.5f, y12 = (y1 + y2) * 0.5f;
float x23 = (x2 + x3) * 0.5f, y23 = (y2 + y3) * 0.5f;
float x34 = (x3 + x4) * 0.5f, y34 = (y3 + y4) * 0.5f;
float x123 = (x12 + x23) * 0.5f, y123 = (y12 + y23) * 0.5f;
float x234 = (x23 + x34) * 0.5f, y234 = (y23 + y34) * 0.5f;
float x1234 = (x123 + x234) * 0.5f, y1234 = (y123 + y234) * 0.5f;
PathBezierCubicCurveToCasteljau(path, x1, y1, x12, y12, x123, y123, x1234, y1234, tess_tol, level + 1);
PathBezierCubicCurveToCasteljau(path, x1234, y1234, x234, y234, x34, y34, x4, y4, tess_tol, level + 1);
}
}
void ImDrawList::PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments)
static void PathBezierQuadraticCurveToCasteljau(ImVector<ImVec2>* path, float x1, float y1, float x2, float y2, float x3, float y3, float tess_tol, int level)
{
float dx = x3 - x1, dy = y3 - y1;
float det = (x2 - x3) * dy - (y2 - y3) * dx;
if (det * det * 4.0f < tess_tol * (dx * dx + dy * dy))
{
path->push_back(ImVec2(x3, y3));
}
else if (level < 10)
{
float x12 = (x1 + x2) * 0.5f, y12 = (y1 + y2) * 0.5f;
float x23 = (x2 + x3) * 0.5f, y23 = (y2 + y3) * 0.5f;
float x123 = (x12 + x23) * 0.5f, y123 = (y12 + y23) * 0.5f;
PathBezierQuadraticCurveToCasteljau(path, x1, y1, x12, y12, x123, y123, tess_tol, level + 1);
PathBezierQuadraticCurveToCasteljau(path, x123, y123, x23, y23, x3, y3, tess_tol, level + 1);
}
}
void ImDrawList::PathBezierCubicCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments)
{
ImVec2 p1 = _Path.back();
if (num_segments == 0)
{
PathBezierToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, _Data->CurveTessellationTol, 0); // Auto-tessellated
PathBezierCubicCurveToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, _Data->CurveTessellationTol, 0); // Auto-tessellated
}
else
{
float t_step = 1.0f / (float)num_segments;
for (int i_step = 1; i_step <= num_segments; i_step++)
_Path.push_back(ImBezierCalc(p1, p2, p3, p4, t_step * i_step));
_Path.push_back(ImBezierCubicCalc(p1, p2, p3, p4, t_step * i_step));
}
}
void ImDrawList::PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3, int num_segments)
{
ImVec2 p1 = _Path.back();
if (num_segments == 0)
{
PathBezierQuadraticCurveToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, _Data->CurveTessellationTol, 0);// Auto-tessellated
}
else
{
float t_step = 1.0f / (float)num_segments;
for (int i_step = 1; i_step <= num_segments; i_step++)
_Path.push_back(ImBezierQuadraticCalc(p1, p2, p3, t_step * i_step));
}
}
@ -1235,7 +1286,7 @@ void ImDrawList::AddCircle(const ImVec2& center, float radius, ImU32 col, int nu
if (num_segments <= 0)
{
// Automatic segment count
const int radius_idx = (int)radius - 1;
const int radius_idx = (int)radius;
if (radius_idx < IM_ARRAYSIZE(_Data->CircleSegmentCounts))
num_segments = _Data->CircleSegmentCounts[radius_idx]; // Use cached value
else
@ -1265,7 +1316,7 @@ void ImDrawList::AddCircleFilled(const ImVec2& center, float radius, ImU32 col,
if (num_segments <= 0)
{
// Automatic segment count
const int radius_idx = (int)radius - 1;
const int radius_idx = (int)radius;
if (radius_idx < IM_ARRAYSIZE(_Data->CircleSegmentCounts))
num_segments = _Data->CircleSegmentCounts[radius_idx]; // Use cached value
else
@ -1311,13 +1362,24 @@ void ImDrawList::AddNgonFilled(const ImVec2& center, float radius, ImU32 col, in
}
// Cubic Bezier takes 4 controls points
void ImDrawList::AddBezierCurve(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments)
void ImDrawList::AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments)
{
if ((col & IM_COL32_A_MASK) == 0)
return;
PathLineTo(p1);
PathBezierCurveTo(p2, p3, p4, num_segments);
PathBezierCubicCurveTo(p2, p3, p4, num_segments);
PathStroke(col, false, thickness);
}
// Quadratic Bezier takes 3 controls points
void ImDrawList::AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness, int num_segments)
{
if ((col & IM_COL32_A_MASK) == 0)
return;
PathLineTo(p1);
PathBezierQuadraticCurveTo(p2, p3, num_segments);
PathStroke(col, false, thickness);
}
@ -1656,25 +1718,13 @@ void ImGui::ShadeVertsLinearUV(ImDrawList* draw_list, int vert_start_idx, int ve
ImFontConfig::ImFontConfig()
{
FontData = NULL;
FontDataSize = 0;
memset(this, 0, sizeof(*this));
FontDataOwnedByAtlas = true;
FontNo = 0;
SizePixels = 0.0f;
OversampleH = 3; // FIXME: 2 may be a better default?
OversampleV = 1;
PixelSnapH = false;
GlyphExtraSpacing = ImVec2(0.0f, 0.0f);
GlyphOffset = ImVec2(0.0f, 0.0f);
GlyphRanges = NULL;
GlyphMinAdvanceX = 0.0f;
GlyphMaxAdvanceX = FLT_MAX;
MergeMode = false;
RasterizerFlags = 0x00;
RasterizerMultiply = 1.0f;
EllipsisChar = (ImWchar)-1;
memset(Name, 0, sizeof(Name));
DstFont = NULL;
}
//-----------------------------------------------------------------------------
@ -1731,17 +1781,8 @@ static const ImVec2 FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[ImGuiMouseCursor_COUNT][3
ImFontAtlas::ImFontAtlas()
{
Locked = false;
Flags = ImFontAtlasFlags_None;
TexID = (ImTextureID)NULL;
TexDesiredWidth = 0;
memset(this, 0, sizeof(*this));
TexGlyphPadding = 1;
TexPixelsAlpha8 = NULL;
TexPixelsRGBA32 = NULL;
TexWidth = TexHeight = 0;
TexUvScale = ImVec2(0.0f, 0.0f);
TexUvWhitePixel = ImVec2(0.0f, 0.0f);
PackIdMouseCursors = PackIdLines = -1;
}
@ -2027,7 +2068,26 @@ bool ImFontAtlas::GetMouseCursorTexData(ImGuiMouseCursor cursor_type, ImVec2* ou
bool ImFontAtlas::Build()
{
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!");
return ImFontAtlasBuildWithStbTruetype(this);
// Select builder
// - Note that we do not reassign to atlas->FontBuilderIO, since it is likely to point to static data which
// may mess with some hot-reloading schemes. If you need to assign to this (for dynamic selection) AND are
// using a hot-reloading scheme that messes up static data, store your own instance of ImFontBuilderIO somewhere
// and point to it instead of pointing directly to return value of the GetBuilderXXX functions.
const ImFontBuilderIO* builder_io = FontBuilderIO;
if (builder_io == NULL)
{
#ifdef IMGUI_ENABLE_FREETYPE
builder_io = ImGuiFreeType::GetBuilderForFreeType();
#elif defined(IMGUI_ENABLE_STB_TRUETYPE)
builder_io = ImFontAtlasGetBuilderForStbTruetype();
#else
IM_ASSERT(0); // Invalid Build function
#endif
}
// Build
return builder_io->FontBuilder_Build(this);
}
void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_brighten_factor)
@ -2047,6 +2107,7 @@ void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsig
data[i] = table[data[i]];
}
#ifdef IMGUI_ENABLE_STB_TRUETYPE
// Temporary data for one source font (multiple source fonts can be merged into one destination ImFont)
// (C++03 doesn't allow instancing ImVector<> with function-local types so we declare the type here.)
struct ImFontBuildSrcData
@ -2084,7 +2145,7 @@ static void UnpackBitVectorToFlatIndexList(const ImBitVector* in, ImVector<int>*
out->push_back((int)(((it - it_begin) << 5) + bit_n));
}
bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
{
IM_ASSERT(atlas->ConfigData.Size > 0);
@ -2117,10 +2178,11 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
for (int output_i = 0; output_i < atlas->Fonts.Size && src_tmp.DstIndex == -1; output_i++)
if (cfg.DstFont == atlas->Fonts[output_i])
src_tmp.DstIndex = output_i;
IM_ASSERT(src_tmp.DstIndex != -1); // cfg.DstFont not pointing within atlas->Fonts[] array?
if (src_tmp.DstIndex == -1)
{
IM_ASSERT(src_tmp.DstIndex != -1); // cfg.DstFont not pointing within atlas->Fonts[] array?
return false;
}
// Initialize helper structure for font loading and verify that the TTF/OTF data is correct
const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)cfg.FontData, cfg.FontNo);
IM_ASSERT(font_offset >= 0 && "FontData is incorrect, or FontNo cannot be found.");
@ -2336,6 +2398,15 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
return true;
}
const ImFontBuilderIO* ImFontAtlasGetBuilderForStbTruetype()
{
static ImFontBuilderIO io;
io.FontBuilder_Build = ImFontAtlasBuildWithStbTruetype;
return &io;
}
#endif // IMGUI_ENABLE_STB_TRUETYPE
void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent)
{
if (!font_config->MergeMode)
@ -2378,7 +2449,7 @@ void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opa
}
}
void ImFontAtlasBuildRender1bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned char in_marker_pixel_value)
void ImFontAtlasBuildRender8bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned char in_marker_pixel_value)
{
IM_ASSERT(x >= 0 && x + w <= atlas->TexWidth);
IM_ASSERT(y >= 0 && y + h <= atlas->TexHeight);
@ -2388,6 +2459,16 @@ void ImFontAtlasBuildRender1bppRectFromString(ImFontAtlas* atlas, int x, int y,
out_pixel[off_x] = (in_str[off_x] == in_marker_char) ? in_marker_pixel_value : 0x00;
}
void ImFontAtlasBuildRender32bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned int in_marker_pixel_value)
{
IM_ASSERT(x >= 0 && x + w <= atlas->TexWidth);
IM_ASSERT(y >= 0 && y + h <= atlas->TexHeight);
unsigned int* out_pixel = atlas->TexPixelsRGBA32 + x + (y * atlas->TexWidth);
for (int off_y = 0; off_y < h; off_y++, out_pixel += atlas->TexWidth, in_str += w)
for (int off_x = 0; off_x < w; off_x++)
out_pixel[off_x] = (in_str[off_x] == in_marker_char) ? in_marker_pixel_value : IM_COL32_BLACK_TRANS;
}
static void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas)
{
ImFontAtlasCustomRect* r = atlas->GetCustomRectByIndex(atlas->PackIdMouseCursors);
@ -2400,15 +2481,30 @@ static void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas)
IM_ASSERT(r->Width == FONT_ATLAS_DEFAULT_TEX_DATA_W * 2 + 1 && r->Height == FONT_ATLAS_DEFAULT_TEX_DATA_H);
const int x_for_white = r->X;
const int x_for_black = r->X + FONT_ATLAS_DEFAULT_TEX_DATA_W + 1;
ImFontAtlasBuildRender1bppRectFromString(atlas, x_for_white, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, '.', 0xFF);
ImFontAtlasBuildRender1bppRectFromString(atlas, x_for_black, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, 'X', 0xFF);
if (atlas->TexPixelsAlpha8 != NULL)
{
ImFontAtlasBuildRender8bppRectFromString(atlas, x_for_white, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, '.', 0xFF);
ImFontAtlasBuildRender8bppRectFromString(atlas, x_for_black, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, 'X', 0xFF);
}
else
{
ImFontAtlasBuildRender32bppRectFromString(atlas, x_for_white, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, '.', IM_COL32_WHITE);
ImFontAtlasBuildRender32bppRectFromString(atlas, x_for_black, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, 'X', IM_COL32_WHITE);
}
}
else
{
// Render 4 white pixels
IM_ASSERT(r->Width == 2 && r->Height == 2);
const int offset = (int)r->X + (int)r->Y * w;
atlas->TexPixelsAlpha8[offset] = atlas->TexPixelsAlpha8[offset + 1] = atlas->TexPixelsAlpha8[offset + w] = atlas->TexPixelsAlpha8[offset + w + 1] = 0xFF;
if (atlas->TexPixelsAlpha8 != NULL)
{
atlas->TexPixelsAlpha8[offset] = atlas->TexPixelsAlpha8[offset + 1] = atlas->TexPixelsAlpha8[offset + w] = atlas->TexPixelsAlpha8[offset + w + 1] = 0xFF;
}
else
{
atlas->TexPixelsRGBA32[offset] = atlas->TexPixelsRGBA32[offset + 1] = atlas->TexPixelsRGBA32[offset + w] = atlas->TexPixelsRGBA32[offset + w + 1] = IM_COL32_WHITE;
}
}
atlas->TexUvWhitePixel = ImVec2((r->X + 0.5f) * atlas->TexUvScale.x, (r->Y + 0.5f) * atlas->TexUvScale.y);
}
@ -2431,10 +2527,30 @@ static void ImFontAtlasBuildRenderLinesTexData(ImFontAtlas* atlas)
// Write each slice
IM_ASSERT(pad_left + line_width + pad_right == r->Width && y < r->Height); // Make sure we're inside the texture bounds before we start writing pixels
unsigned char* write_ptr = &atlas->TexPixelsAlpha8[r->X + ((r->Y + y) * atlas->TexWidth)];
memset(write_ptr, 0x00, pad_left);
memset(write_ptr + pad_left, 0xFF, line_width);
memset(write_ptr + pad_left + line_width, 0x00, pad_right);
if (atlas->TexPixelsAlpha8 != NULL)
{
unsigned char* write_ptr = &atlas->TexPixelsAlpha8[r->X + ((r->Y + y) * atlas->TexWidth)];
for (unsigned int i = 0; i < pad_left; i++)
*(write_ptr + i) = 0x00;
for (unsigned int i = 0; i < line_width; i++)
*(write_ptr + pad_left + i) = 0xFF;
for (unsigned int i = 0; i < pad_right; i++)
*(write_ptr + pad_left + line_width + i) = 0x00;
}
else
{
unsigned int* write_ptr = &atlas->TexPixelsRGBA32[r->X + ((r->Y + y) * atlas->TexWidth)];
for (unsigned int i = 0; i < pad_left; i++)
*(write_ptr + i) = IM_COL32_BLACK_TRANS;
for (unsigned int i = 0; i < line_width; i++)
*(write_ptr + pad_left + i) = IM_COL32_WHITE;
for (unsigned int i = 0; i < pad_right; i++)
*(write_ptr + pad_left + line_width + i) = IM_COL32_BLACK_TRANS;
}
// Calculate UVs for this line
ImVec2 uv0 = ImVec2((float)(r->X + pad_left - 1), (float)(r->Y + y)) * atlas->TexUvScale;
@ -2469,7 +2585,7 @@ void ImFontAtlasBuildInit(ImFontAtlas* atlas)
void ImFontAtlasBuildFinish(ImFontAtlas* atlas)
{
// Render into our custom data blocks
IM_ASSERT(atlas->TexPixelsAlpha8 != NULL);
IM_ASSERT(atlas->TexPixelsAlpha8 != NULL || atlas->TexPixelsRGBA32 != NULL);
ImFontAtlasBuildRenderDefaultTexData(atlas);
ImFontAtlasBuildRenderLinesTexData(atlas);
@ -2951,6 +3067,7 @@ void ImFont::AddGlyph(const ImFontConfig* cfg, ImWchar codepoint, float x0, floa
ImFontGlyph& glyph = Glyphs.back();
glyph.Codepoint = (unsigned int)codepoint;
glyph.Visible = (x0 != x1) && (y0 != y1);
glyph.Colored = false;
glyph.X0 = x0;
glyph.Y0 = y0;
glyph.X1 = x1;
@ -3201,6 +3318,8 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
const ImFontGlyph* glyph = FindGlyph(c);
if (!glyph || !glyph->Visible)
return;
if (glyph->Colored)
col |= ~IM_COL32_A_MASK;
float scale = (size >= 0.0f) ? (size / FontSize) : 1.0f;
pos.x = IM_FLOOR(pos.x);
pos.y = IM_FLOOR(pos.y);
@ -3263,6 +3382,8 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
ImDrawIdx* idx_write = draw_list->_IdxWritePtr;
unsigned int vtx_current_idx = draw_list->_VtxCurrentIdx;
const ImU32 col_untinted = col | ~IM_COL32_A_MASK;
while (s < text_end)
{
if (word_wrap_enabled)
@ -3368,14 +3489,17 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
}
}
// Support for untinted glyphs
ImU32 glyph_col = glyph->Colored ? col_untinted : col;
// We are NOT calling PrimRectUV() here because non-inlined causes too much overhead in a debug builds. Inlined here:
{
idx_write[0] = (ImDrawIdx)(vtx_current_idx); idx_write[1] = (ImDrawIdx)(vtx_current_idx+1); idx_write[2] = (ImDrawIdx)(vtx_current_idx+2);
idx_write[3] = (ImDrawIdx)(vtx_current_idx); idx_write[4] = (ImDrawIdx)(vtx_current_idx+2); idx_write[5] = (ImDrawIdx)(vtx_current_idx+3);
vtx_write[0].pos.x = x1; vtx_write[0].pos.y = y1; vtx_write[0].col = col; vtx_write[0].uv.x = u1; vtx_write[0].uv.y = v1;
vtx_write[1].pos.x = x2; vtx_write[1].pos.y = y1; vtx_write[1].col = col; vtx_write[1].uv.x = u2; vtx_write[1].uv.y = v1;
vtx_write[2].pos.x = x2; vtx_write[2].pos.y = y2; vtx_write[2].col = col; vtx_write[2].uv.x = u2; vtx_write[2].uv.y = v2;
vtx_write[3].pos.x = x1; vtx_write[3].pos.y = y2; vtx_write[3].col = col; vtx_write[3].uv.x = u1; vtx_write[3].uv.y = v2;
vtx_write[0].pos.x = x1; vtx_write[0].pos.y = y1; vtx_write[0].col = glyph_col; vtx_write[0].uv.x = u1; vtx_write[0].uv.y = v1;
vtx_write[1].pos.x = x2; vtx_write[1].pos.y = y1; vtx_write[1].col = glyph_col; vtx_write[1].uv.x = u2; vtx_write[1].uv.y = v1;
vtx_write[2].pos.x = x2; vtx_write[2].pos.y = y2; vtx_write[2].col = glyph_col; vtx_write[2].uv.x = u2; vtx_write[2].uv.y = v2;
vtx_write[3].pos.x = x1; vtx_write[3].pos.y = y2; vtx_write[3].col = glyph_col; vtx_write[3].uv.x = u1; vtx_write[3].uv.y = v2;
vtx_write += 4;
vtx_current_idx += 4;
idx_write += 6;

View File

@ -1,4 +1,4 @@
// dear imgui, v1.80 WIP
// dear imgui, v1.81
// (internal structures/api)
// You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility!
@ -29,7 +29,8 @@ Index of this file:
// [SECTION] ImGuiWindowTempData, ImGuiWindow
// [SECTION] Tab bar, Tab item support
// [SECTION] Table support
// [SECTION] Internal API
// [SECTION] ImGui internal API
// [SECTION] ImFontAtlas internal API
// [SECTION] Test Engine specific hooks (imgui_test_engine)
*/
@ -83,6 +84,12 @@ Index of this file:
#error Use IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS
#endif
// Enable stb_truetype by default unless FreeType is enabled.
// You can compile with both by defining both IMGUI_ENABLE_FREETYPE and IMGUI_ENABLE_STB_TRUETYPE together.
#ifndef IMGUI_ENABLE_FREETYPE
#define IMGUI_ENABLE_STB_TRUETYPE
#endif
//-----------------------------------------------------------------------------
// [SECTION] Forward declarations
//-----------------------------------------------------------------------------
@ -178,7 +185,7 @@ namespace ImStb
#define IMGUI_DEBUG_LOG_NAV(...) ((void)0) // Disable log
// Static Asserts
#if (__cplusplus >= 201100)
#if (__cplusplus >= 201100) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201100)
#define IM_STATIC_ASSERT(_COND) static_assert(_COND, "")
#else
#define IM_STATIC_ASSERT(_COND) typedef char static_assertion_##__line__[(_COND)?1:-1]
@ -396,9 +403,10 @@ static inline float ImLinearSweep(float current, float target, float speed)
static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); }
// Helpers: Geometry
IMGUI_API ImVec2 ImBezierCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t); // Cubic Bezier
IMGUI_API ImVec2 ImBezierClosestPoint(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, int num_segments); // For curves with explicit number of segments
IMGUI_API ImVec2 ImBezierClosestPointCasteljau(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, float tess_tol);// For auto-tessellated curves you can use tess_tol = style.CurveTessellationTol
IMGUI_API ImVec2 ImBezierCubicCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t);
IMGUI_API ImVec2 ImBezierCubicClosestPoint(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, int num_segments); // For curves with explicit number of segments
IMGUI_API ImVec2 ImBezierCubicClosestPointCasteljau(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, float tess_tol);// For auto-tessellated curves you can use tess_tol = style.CurveTessellationTol
IMGUI_API ImVec2 ImBezierQuadraticCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, float t);
IMGUI_API ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p);
IMGUI_API bool ImTriangleContainsPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p);
IMGUI_API ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p);
@ -465,8 +473,9 @@ struct IMGUI_API ImRect
inline bool ImBitArrayTestBit(const ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); return (arr[n >> 5] & mask) != 0; }
inline void ImBitArrayClearBit(ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); arr[n >> 5] &= ~mask; }
inline void ImBitArraySetBit(ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); arr[n >> 5] |= mask; }
inline void ImBitArraySetBitRange(ImU32* arr, int n, int n2)
inline void ImBitArraySetBitRange(ImU32* arr, int n, int n2) // Works on range [n..n2)
{
n2--;
while (n <= n2)
{
int a_mod = (n & 31);
@ -484,11 +493,12 @@ struct IMGUI_API ImBitArray
{
ImU32 Storage[(BITCOUNT + 31) >> 5];
ImBitArray() { }
void ClearBits() { memset(Storage, 0, sizeof(Storage)); }
void ClearAllBits() { memset(Storage, 0, sizeof(Storage)); }
void SetAllBits() { memset(Storage, 255, sizeof(Storage)); }
bool TestBit(int n) const { IM_ASSERT(n < BITCOUNT); return ImBitArrayTestBit(Storage, n); }
void SetBit(int n) { IM_ASSERT(n < BITCOUNT); ImBitArraySetBit(Storage, n); }
void ClearBit(int n) { IM_ASSERT(n < BITCOUNT); ImBitArrayClearBit(Storage, n); }
void SetBitRange(int n1, int n2) { ImBitArraySetBitRange(Storage, n1, n2); }
void SetBitRange(int n, int n2) { ImBitArraySetBitRange(Storage, n, n2); } // Works on range [n..n2)
};
// Helper: ImBitVector
@ -607,6 +617,7 @@ struct IMGUI_API ImChunkStream
//-----------------------------------------------------------------------------
// ImDrawList: Helper function to calculate a circle's segment count given its radius and a "maximum error" value.
// FIXME: the minimum number of auto-segment may be undesirably high for very small radiuses (e.g. 1.0f)
#define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN 12
#define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX 512
#define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(_RAD,_MAXERROR) ImClamp((int)((IM_PI * 2.0f) / ImAcos(((_RAD) - (_MAXERROR)) / (_RAD))), IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN, IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX)
@ -630,7 +641,7 @@ struct IMGUI_API ImDrawListSharedData
// [Internal] Lookup tables
ImVec2 ArcFastVtx[12 * IM_DRAWLIST_ARCFAST_TESSELLATION_MULTIPLIER]; // FIXME: Bake rounded corners fill/borders in atlas
ImU8 CircleSegmentCounts[64]; // Precomputed segment count for given radius (array index + 1) before we calculate it dynamically (to avoid calculation overhead)
ImU8 CircleSegmentCounts[64]; // Precomputed segment count for given radius before we calculate it dynamically (to avoid calculation overhead)
const ImVec4* TexUvLines; // UV of anti-aliased lines in the atlas
ImDrawListSharedData();
@ -641,8 +652,9 @@ struct ImDrawDataBuilder
{
ImVector<ImDrawList*> Layers[2]; // Global layers for: regular, tooltip
void Clear() { for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].resize(0); }
void ClearFreeMemory() { for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].clear(); }
void Clear() { for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].resize(0); }
void ClearFreeMemory() { for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].clear(); }
int GetDrawListCount() const { int count = 0; for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) count += Layers[n].Size; return count; }
IMGUI_API void FlattenIntoSingleLayer();
};
@ -1135,9 +1147,26 @@ struct ImGuiOldColumns
// [SECTION] Viewport support
//-----------------------------------------------------------------------------
#ifdef IMGUI_HAS_VIEWPORT
// <this is filled in 'docking' branch>
#endif // #ifdef IMGUI_HAS_VIEWPORT
// ImGuiViewport Private/Internals fields (cardinal sin: we are using inheritance!)
// Every instance of ImGuiViewport is in fact a ImGuiViewportP.
struct ImGuiViewportP : public ImGuiViewport
{
int DrawListsLastFrame[2]; // Last frame number the background (0) and foreground (1) draw lists were used
ImDrawList* DrawLists[2]; // Convenience background (0) and foreground (1) draw lists. We use them to draw software mouser cursor when io.MouseDrawCursor is set and to draw most debug overlays.
ImDrawData DrawDataP;
ImDrawDataBuilder DrawDataBuilder;
ImVec2 WorkOffsetMin; // Work Area: Offset from Pos to top-left corner of Work Area. Generally (0,0) or (0,+main_menu_bar_height). Work Area is Full Area but without menu-bars/status-bars (so WorkArea always fit inside Pos/Size!)
ImVec2 WorkOffsetMax; // Work Area: Offset from Pos+Size to bottom-right corner of Work Area. Generally (0,0) or (0,-status_bar_height).
ImVec2 CurrWorkOffsetMin; // Work Area: Offset being built/increased during current frame
ImVec2 CurrWorkOffsetMax; // Work Area: Offset being built/decreased during current frame
ImGuiViewportP() { DrawListsLastFrame[0] = DrawListsLastFrame[1] = -1; DrawLists[0] = DrawLists[1] = NULL; }
~ImGuiViewportP() { if (DrawLists[0]) IM_DELETE(DrawLists[0]); if (DrawLists[1]) IM_DELETE(DrawLists[1]); }
ImRect GetMainRect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); }
ImRect GetWorkRect() const { return ImRect(WorkPos.x, WorkPos.y, WorkPos.x + WorkSize.x, WorkPos.y + WorkSize.y); }
void UpdateWorkRect() { WorkPos = ImVec2(Pos.x + WorkOffsetMin.x, Pos.y + WorkOffsetMin.y); WorkSize = ImVec2(ImMax(0.0f, Size.x - WorkOffsetMin.x + WorkOffsetMax.x), ImMax(0.0f, Size.y - WorkOffsetMin.y + WorkOffsetMax.y)); }
};
//-----------------------------------------------------------------------------
// [SECTION] Settings support
@ -1219,10 +1248,11 @@ struct IMGUI_API ImGuiStackSizes
//-----------------------------------------------------------------------------
typedef void (*ImGuiContextHookCallback)(ImGuiContext* ctx, ImGuiContextHook* hook);
enum ImGuiContextHookType { ImGuiContextHookType_NewFramePre, ImGuiContextHookType_NewFramePost, ImGuiContextHookType_EndFramePre, ImGuiContextHookType_EndFramePost, ImGuiContextHookType_RenderPre, ImGuiContextHookType_RenderPost, ImGuiContextHookType_Shutdown };
enum ImGuiContextHookType { ImGuiContextHookType_NewFramePre, ImGuiContextHookType_NewFramePost, ImGuiContextHookType_EndFramePre, ImGuiContextHookType_EndFramePost, ImGuiContextHookType_RenderPre, ImGuiContextHookType_RenderPost, ImGuiContextHookType_Shutdown, ImGuiContextHookType_PendingRemoval_ };
struct ImGuiContextHook
{
ImGuiID HookId; // A unique ID assigned by AddContextHook()
ImGuiContextHookType Type;
ImGuiID Owner;
ImGuiContextHookCallback Callback;
@ -1274,9 +1304,11 @@ struct ImGuiContext
float WheelingWindowTimer;
// Item/widgets state and tracking information
ImGuiID HoveredId; // Hovered widget
ImGuiID HoveredId; // Hovered widget, filled during the frame
ImGuiID HoveredIdPreviousFrame;
bool HoveredIdAllowOverlap;
bool HoveredIdUsingMouseWheel; // Hovered widget will use mouse wheel. Blocks scrolling the underlying window.
bool HoveredIdPreviousFrameUsingMouseWheel;
bool HoveredIdDisabled; // At least one widget passed the rect test, but has been discarded by disabled flag or popup inhibit. May be true even if HoveredId == 0.
float HoveredIdTimer; // Measure contiguous hovering time
float HoveredIdNotActiveTimer; // Measure contiguous hovering time where the item has not been active
@ -1289,6 +1321,7 @@ struct ImGuiContext
bool ActiveIdHasBeenPressedBefore; // Track whether the active id led to a press (this is to allow changing between PressOnClick and PressOnRelease without pressing twice). Used by range_select branch.
bool ActiveIdHasBeenEditedBefore; // Was the value associated to the widget Edited over the course of the Active state.
bool ActiveIdHasBeenEditedThisFrame;
bool ActiveIdUsingMouseWheel; // Active widget will want to read mouse wheel. Blocks scrolling the underlying window.
ImU32 ActiveIdUsingNavDirMask; // Active widget will want to read those nav move requests (e.g. can activate a button and move away from it)
ImU32 ActiveIdUsingNavInputMask; // Active widget will want to read those nav inputs.
ImU64 ActiveIdUsingKeyInputMask; // Active widget will want to read those key inputs. When we grow the ImGuiKey enum we'll need to either to order the enum to make useful keys come first, either redesign this into e.g. a small array.
@ -1317,6 +1350,9 @@ struct ImGuiContext
ImVector<ImGuiPopupData>OpenPopupStack; // Which popups are open (persistent)
ImVector<ImGuiPopupData>BeginPopupStack; // Which level of BeginPopup() we are in (reset every frame)
// Viewports
ImVector<ImGuiViewportP*> Viewports; // Active viewports (Size==1 in 'master' branch). Each viewports hold their copy of ImDrawData.
// Gamepad/keyboard Navigation
ImGuiWindow* NavWindow; // Focused window for navigation. Could be called 'FocusWindow'
ImGuiID NavId; // Focused item for navigation
@ -1374,11 +1410,7 @@ struct ImGuiContext
bool FocusTabPressed; //
// Render
ImDrawData DrawData; // Main ImDrawData instance to pass render information to the user
ImDrawDataBuilder DrawDataBuilder;
float DimBgRatio; // 0.0..1.0 animation when fading in a dimming background (for modal window and CTRL+TAB list)
ImDrawList BackgroundDrawList; // First draw list to be rendered.
ImDrawList ForegroundDrawList; // Last draw list to be rendered. This is where we the render software mouse cursor (if io.MouseDrawCursor is set) and most debug overlays.
ImGuiMouseCursor MouseCursor;
// Drag and Drop
@ -1447,12 +1479,15 @@ struct ImGuiContext
ImChunkStream<ImGuiWindowSettings> SettingsWindows; // ImGuiWindow .ini settings entries
ImChunkStream<ImGuiTableSettings> SettingsTables; // ImGuiTable .ini settings entries
ImVector<ImGuiContextHook> Hooks; // Hooks for extensions (e.g. test engine)
ImGuiID HookIdNext; // Next available HookId
// Capture/Logging
bool LogEnabled; // Currently capturing
ImGuiLogType LogType; // Capture target
ImFileHandle LogFile; // If != NULL log to stdout/ file
ImGuiTextBuffer LogBuffer; // Accumulation buffer when log to clipboard. This is pointer so our GImGui static constructor doesn't call heap allocators.
const char* LogNextPrefix;
const char* LogNextSuffix;
float LogLinePosY;
bool LogLineFirstItem;
int LogDepthRef;
@ -1473,7 +1508,7 @@ struct ImGuiContext
int WantTextInputNextFrame;
char TempBuffer[1024 * 3 + 1]; // Temporary text buffer
ImGuiContext(ImFontAtlas* shared_font_atlas) : BackgroundDrawList(&DrawListSharedData), ForegroundDrawList(&DrawListSharedData)
ImGuiContext(ImFontAtlas* shared_font_atlas)
{
Initialized = false;
FontAtlasOwnedByContext = shared_font_atlas ? false : true;
@ -1500,6 +1535,7 @@ struct ImGuiContext
HoveredId = HoveredIdPreviousFrame = 0;
HoveredIdAllowOverlap = false;
HoveredIdUsingMouseWheel = HoveredIdPreviousFrameUsingMouseWheel = false;
HoveredIdDisabled = false;
HoveredIdTimer = HoveredIdNotActiveTimer = 0.0f;
ActiveId = 0;
@ -1511,6 +1547,7 @@ struct ImGuiContext
ActiveIdHasBeenPressedBefore = false;
ActiveIdHasBeenEditedBefore = false;
ActiveIdHasBeenEditedThisFrame = false;
ActiveIdUsingMouseWheel = false;
ActiveIdUsingNavDirMask = 0x00;
ActiveIdUsingNavInputMask = 0x00;
ActiveIdUsingKeyInputMask = 0x00;
@ -1560,8 +1597,6 @@ struct ImGuiContext
FocusTabPressed = false;
DimBgRatio = 0.0f;
BackgroundDrawList._OwnerName = "##Background"; // Give it a name for debugging
ForegroundDrawList._OwnerName = "##Foreground"; // Give it a name for debugging
MouseCursor = ImGuiMouseCursor_Arrow;
DragDropActive = DragDropWithinSource = DragDropWithinTarget = false;
@ -1598,9 +1633,11 @@ struct ImGuiContext
SettingsLoaded = false;
SettingsDirtyTimer = 0.0f;
HookIdNext = 0;
LogEnabled = false;
LogType = ImGuiLogType_None;
LogNextPrefix = LogNextSuffix = NULL;
LogFile = NULL;
LogLinePosY = FLT_MAX;
LogLineFirstItem = false;
@ -1631,7 +1668,8 @@ struct IMGUI_API ImGuiWindowTempData
ImVec2 CursorPos; // Current emitting position, in absolute coordinates.
ImVec2 CursorPosPrevLine;
ImVec2 CursorStartPos; // Initial position after Begin(), generally ~ window position + WindowPadding.
ImVec2 CursorMaxPos; // Used to implicitly calculate the size of our contents, always growing during the frame. Used to calculate window->ContentSize at the beginning of next frame
ImVec2 CursorMaxPos; // Used to implicitly calculate ContentSize at the beginning of next frame, for scrolling range and auto-resize. Always growing during the frame.
ImVec2 IdealMaxPos; // Used to implicitly calculate ContentSizeIdeal at the beginning of next frame, for auto-resize only. Always growing during the frame.
ImVec2 CurrLineSize;
ImVec2 PrevLineSize;
float CurrLineTextBaseOffset; // Baseline offset (0.0f by default on a new line, generally == style.FramePadding.y when a framed item has been added).
@ -1672,10 +1710,10 @@ struct IMGUI_API ImGuiWindowTempData
// Local parameters stacks
// We store the current settings outside of the vectors to increase memory locality (reduce cache misses). The vectors are rarely modified. Also it allows us to not heap allocate for short-lived windows which are not using those settings.
ImGuiItemFlags ItemFlags; // == g.ItemFlagsStack.back()
float ItemWidth; // == ItemWidthStack.back(). 0.0: default, >0.0: width in pixels, <0.0: align xx pixels to the right of window
float TextWrapPos; // == TextWrapPosStack.back() [empty == -1.0f]
ImVector<float> ItemWidthStack;
ImVector<float> TextWrapPosStack;
float ItemWidth; // Current item width (>0.0: width in pixels, <0.0: align xx pixels to the right of window).
float TextWrapPos; // Current text wrap pos.
ImVector<float> ItemWidthStack; // Store item widths to restore (attention: .back() is not == ItemWidth)
ImVector<float> TextWrapPosStack; // Store text wrap pos to restore (attention: .back() is not == TextWrapPos)
ImGuiStackSizes StackSizesOnBegin; // Store size of various stacks for asserting
};
@ -1689,6 +1727,7 @@ struct IMGUI_API ImGuiWindow
ImVec2 Size; // Current size (==SizeFull or collapsed title bar size)
ImVec2 SizeFull; // Size when non collapsed
ImVec2 ContentSize; // Size of contents/scrollable client area (calculated from the extents reach of the cursor) from previous frame. Does not include window decoration or window padding.
ImVec2 ContentSizeIdeal;
ImVec2 ContentSizeExplicit; // Size of contents/scrollable client area explicitly request by the user via SetNextWindowContentSize().
ImVec2 WindowPadding; // Window padding at the time of Begin().
float WindowRounding; // Window rounding at the time of Begin(). May be clamped lower to avoid rendering artifacts with title bar, menu bar etc.
@ -1722,11 +1761,12 @@ struct IMGUI_API ImGuiWindow
ImS8 AutoFitChildAxises;
bool AutoFitOnlyGrows;
ImGuiDir AutoPosLastDirection;
int HiddenFramesCanSkipItems; // Hide the window for N frames
int HiddenFramesCannotSkipItems; // Hide the window for N frames while allowing items to be submitted so we can measure their size
ImGuiCond SetWindowPosAllowFlags; // store acceptable condition flags for SetNextWindowPos() use.
ImGuiCond SetWindowSizeAllowFlags; // store acceptable condition flags for SetNextWindowSize() use.
ImGuiCond SetWindowCollapsedAllowFlags; // store acceptable condition flags for SetNextWindowCollapsed() use.
ImS8 HiddenFramesCanSkipItems; // Hide the window for N frames
ImS8 HiddenFramesCannotSkipItems; // Hide the window for N frames while allowing items to be submitted so we can measure their size
ImS8 HiddenFramesForRenderOnly; // Hide the window until frame N at Render() time only
ImGuiCond SetWindowPosAllowFlags : 8; // store acceptable condition flags for SetNextWindowPos() use.
ImGuiCond SetWindowSizeAllowFlags : 8; // store acceptable condition flags for SetNextWindowSize() use.
ImGuiCond SetWindowCollapsedAllowFlags : 8; // store acceptable condition flags for SetNextWindowCollapsed() use.
ImVec2 SetWindowPosVal; // store window position when using a non-zero Pivot (position set needs to be processed when we know the window size)
ImVec2 SetWindowPosPivot; // store window pivot for positioning. ImVec2(0, 0) when positioning from top-left corner; ImVec2(0.5f, 0.5f) for centering; ImVec2(1, 1) for bottom right.
@ -1899,24 +1939,23 @@ typedef ImU8 ImGuiTableDrawChannelIdx;
// [Internal] sizeof() ~ 104
// We use the terminology "Enabled" to refer to a column that is not Hidden by user/api.
// We use the terminology "Clipped" to refer to a column that is out of sight because of scrolling/clipping.
// We use the terminology "Clipped" to refer to a column that is out of sight because of scrolling/clipping.
// This is in contrast with some user-facing api such as IsItemVisible() / IsRectVisible() which use "Visible" to mean "not clipped".
struct ImGuiTableColumn
{
ImRect ClipRect; // Clipping rectangle for the column
ImGuiID UserID; // Optional, value passed to TableSetupColumn()
ImGuiTableColumnFlags FlagsIn; // Flags as they were provided by user. See ImGuiTableColumnFlags_
ImGuiTableColumnFlags Flags; // Effective flags. See ImGuiTableColumnFlags_
ImGuiTableColumnFlags Flags; // Flags after some patching (not directly same as provided by user). See ImGuiTableColumnFlags_
float WidthGiven; // Final/actual width visible == (MaxX - MinX), locked in TableUpdateLayout(). May be > WidthRequest to honor minimum width, may be < WidthRequest to honor shrinking columns down in tight space.
float MinX; // Absolute positions
float MaxX;
float InitStretchWeightOrWidth; // Value passed to TableSetupColumn(). For Width it is a content width (_without padding_).
float StretchWeight; // Master width weight when (Flags & _WidthStretch). Often around ~1.0f initially.
float WidthAuto; // Automatic width
float WidthRequest; // Master width absolute value when !(Flags & _WidthStretch). When Stretch this is derived every frame from StretchWeight in TableUpdateLayout()
float WidthGiven; // Final/actual width visible == (MaxX - MinX), locked in TableUpdateLayout(). May be > WidthRequest to honor minimum width, may be < WidthRequest to honor shrinking columns down in tight space.
float WorkMinX; // Start position for the frame, currently ~(MinX + CellPaddingX)
float WorkMaxX;
float ItemWidth;
float WidthAuto; // Automatic width
float StretchWeight; // Master width weight when (Flags & _WidthStretch). Often around ~1.0f initially.
float InitStretchWeightOrWidth; // Value passed to TableSetupColumn(). For Width it is a content width (_without padding_).
ImRect ClipRect; // Clipping rectangle for the column
ImGuiID UserID; // Optional, value passed to TableSetupColumn()
float WorkMinX; // Contents region min ~(MinX + CellPaddingX + CellSpacingX1) == cursor start position when entering column
float WorkMaxX; // Contents region max ~(MaxX - CellPaddingX - CellSpacingX2)
float ItemWidth; // Current item width for the column, preserved across rows
float ContentMaxXFrozen; // Contents maximum position for frozen rows (apart from headers), from which we can infer content width.
float ContentMaxXUnfrozen;
float ContentMaxXHeadersUsed; // Contents maximum position for headers rows (regardless of freezing). TableHeader() automatically softclip itself + report ideal desired size, to avoid creating extraneous draw calls
@ -1938,9 +1977,12 @@ struct ImGuiTableColumn
bool IsSkipItems; // Do we want item submissions to this column to be completely ignored (no layout will happen).
bool IsPreserveWidthAuto;
ImS8 NavLayerCurrent; // ImGuiNavLayer in 1 byte
ImS8 SortDirection; // ImGuiSortDirection_Ascending or ImGuiSortDirection_Descending
ImU8 AutoFitQueue; // Queue of 8 values for the next 8 frames to request auto-fit
ImU8 CannotSkipItemsQueue; // Queue of 8 values for the next 8 frames to disable Clipped/SkipItem
ImU8 SortDirection : 2; // ImGuiSortDirection_Ascending or ImGuiSortDirection_Descending
ImU8 SortDirectionsAvailCount : 2; // Number of available sort directions (0 to 3)
ImU8 SortDirectionsAvailMask : 4; // Mask of available sort directions (1-bit each)
ImU8 SortDirectionsAvailList; // Ordered of available sort directions (2-bits each)
ImGuiTableColumn()
{
@ -1963,7 +2005,7 @@ struct ImGuiTableCellData
ImGuiTableColumnIdx Column; // Column number
};
// FIXME-TABLES: transient data could be stored in a per-stacked table structure: DrawSplitter, SortSpecs, incoming RowData
// FIXME-TABLE: transient data could be stored in a per-stacked table structure: DrawSplitter, SortSpecs, incoming RowData
struct ImGuiTable
{
ImGuiID ID;
@ -1998,6 +2040,7 @@ struct ImGuiTable
float BorderX1;
float BorderX2;
float HostIndentX;
float MinColumnWidth;
float OuterPaddingX;
float CellPaddingX; // Padding from each borders
float CellPaddingY;
@ -2006,22 +2049,26 @@ struct ImGuiTable
float LastOuterHeight; // Outer height from last frame
float LastFirstRowHeight; // Height of first row from last frame
float InnerWidth; // User value passed to BeginTable(), see comments at the top of BeginTable() for details.
float ColumnsTotalWidth; // Sum of current column width
float ColumnsGivenWidth; // Sum of current column width
float ColumnsAutoFitWidth; // Sum of ideal column width in order nothing to be clipped, used for auto-fitting and content width submission in outer window
float ResizedColumnNextWidth;
float ResizeLockMinContentsX2; // Lock minimum contents width while resizing down in order to not create feedback loops. But we allow growing the table.
float RefScale; // Reference scale to be able to rescale columns on font/dpi changes.
ImRect OuterRect; // Note: OuterRect.Max.y is often FLT_MAX until EndTable(), unless a height has been specified in BeginTable().
ImRect OuterRect; // Note: for non-scrolling table, OuterRect.Max.y is often FLT_MAX until EndTable(), unless a height has been specified in BeginTable().
ImRect InnerRect; // InnerRect but without decoration. As with OuterRect, for non-scrolling tables, InnerRect.Max.y is
ImRect WorkRect;
ImRect InnerClipRect;
ImRect BgClipRect; // We use this to cpu-clip cell background color fill
ImRect BgClipRectForDrawCmd;
ImRect Bg0ClipRectForDrawCmd; // Actual ImDrawCmd clip rect for BG0/1 channel. This tends to be == OuterWindow->ClipRect at BeginTable() because output in BG0/BG1 is cpu-clipped
ImRect Bg2ClipRectForDrawCmd; // Actual ImDrawCmd clip rect for BG2 channel. This tends to be a correct, tight-fit, because output to BG2 are done by widgets relying on regular ClipRect.
ImRect HostClipRect; // This is used to check if we can eventually merge our columns draw calls into the current draw call of the current window.
ImRect HostBackupWorkRect; // Backup of InnerWindow->WorkRect at the end of BeginTable()
ImRect HostBackupParentWorkRect; // Backup of InnerWindow->ParentWorkRect at the end of BeginTable()
ImRect HostBackupClipRect; // Backup of InnerWindow->ClipRect during PushTableBackground()/PopTableBackground()
ImRect HostBackupInnerClipRect; // Backup of InnerWindow->ClipRect during PushTableBackground()/PopTableBackground()
ImVec2 HostBackupPrevLineSize; // Backup of InnerWindow->DC.PrevLineSize at the end of BeginTable()
ImVec2 HostBackupCurrLineSize; // Backup of InnerWindow->DC.CurrLineSize at the end of BeginTable()
ImVec2 HostBackupCursorMaxPos; // Backup of InnerWindow->DC.CursorMaxPos at the end of BeginTable()
ImVec2 UserOuterSize; // outer_size.x passed to BeginTable()
ImVec1 HostBackupColumnsOffset; // Backup of OuterWindow->DC.ColumnsOffset at the end of BeginTable()
float HostBackupItemWidth; // Backup of OuterWindow->DC.ItemWidth at the end of BeginTable()
int HostBackupItemWidthStackSize;// Backup of OuterWindow->DC.ItemWidthStack.Size at the end of BeginTable()
@ -2038,14 +2085,15 @@ struct ImGuiTable
ImGuiTableColumnIdx DeclColumnsCount; // Count calls to TableSetupColumn()
ImGuiTableColumnIdx HoveredColumnBody; // Index of column whose visible region is being hovered. Important: == ColumnsCount when hovering empty region after the right-most column!
ImGuiTableColumnIdx HoveredColumnBorder; // Index of column whose right-border is being hovered (for resizing).
ImGuiTableColumnIdx AutoFitSingleStretchColumn; // Index of single stretch column requesting auto-fit.
ImGuiTableColumnIdx AutoFitSingleColumn; // Index of single column requesting auto-fit.
ImGuiTableColumnIdx ResizedColumn; // Index of column being resized. Reset when InstanceCurrent==0.
ImGuiTableColumnIdx LastResizedColumn; // Index of column being resized from previous frame.
ImGuiTableColumnIdx HeldHeaderColumn; // Index of column header being held.
ImGuiTableColumnIdx ReorderColumn; // Index of column being reordered. (not cleared)
ImGuiTableColumnIdx ReorderColumnDir; // -1 or +1
ImGuiTableColumnIdx LeftMostStretchedColumn; // Index of left-most stretched column.
ImGuiTableColumnIdx RightMostStretchedColumn; // Index of right-most stretched column.
ImGuiTableColumnIdx RightMostEnabledColumn; // Index of right-most non-hidden column.
ImGuiTableColumnIdx LeftMostStretchedColumnDisplayOrder; // Display order of left-most stretched column.
ImGuiTableColumnIdx ContextPopupColumn; // Column right-clicked on, of -1 if opening context menu from a neutral/empty spot
ImGuiTableColumnIdx FreezeRowsRequest; // Requested frozen rows count
ImGuiTableColumnIdx FreezeRowsCount; // Actual frozen row count (== FreezeRowsRequest, or == 0 when no scrolling offset)
@ -2053,8 +2101,8 @@ struct ImGuiTable
ImGuiTableColumnIdx FreezeColumnsCount; // Actual frozen columns count (== FreezeColumnsRequest, or == 0 when no scrolling offset)
ImGuiTableColumnIdx RowCellDataCurrent; // Index of current RowCellData[] entry in current row
ImGuiTableDrawChannelIdx DummyDrawChannel; // Redirect non-visible columns here.
ImGuiTableDrawChannelIdx Bg1DrawChannelCurrent; // For Selectable() and other widgets drawing accross columns after the freezing line. Index within DrawSplitter.Channels[]
ImGuiTableDrawChannelIdx Bg1DrawChannelUnfrozen;
ImGuiTableDrawChannelIdx Bg2DrawChannelCurrent; // For Selectable() and other widgets drawing across columns after the freezing line. Index within DrawSplitter.Channels[]
ImGuiTableDrawChannelIdx Bg2DrawChannelUnfrozen;
bool IsLayoutLocked; // Set by TableUpdateLayout() which is called when beginning the first row.
bool IsInsideRow; // Set when inside TableBeginRow()/TableEndRow().
bool IsInitializing;
@ -2066,12 +2114,13 @@ struct ImGuiTable
bool IsDefaultDisplayOrder; // Set when display order is unchanged from default (DisplayOrder contains 0...Count-1)
bool IsResetAllRequest;
bool IsResetDisplayOrderRequest;
bool IsUnfrozen; // Set when we got past the frozen row.
bool IsUnfrozenRows; // Set when we got past the frozen row.
bool IsDefaultSizingPolicy; // Set if user didn't explicitly set a sizing policy in BeginTable()
bool MemoryCompacted;
bool HostSkipItems; // Backup of InnerWindow->SkipItem at the end of BeginTable(), because we will overwrite InnerWindow->SkipItem on a per-column basis
IMGUI_API ImGuiTable();
IMGUI_API ~ImGuiTable();
IMGUI_API ImGuiTable() { memset(this, 0, sizeof(*this)); LastFrameActive = -1; }
IMGUI_API ~ImGuiTable() { IM_FREE(RawData); }
};
// sizeof() ~ 12
@ -2115,7 +2164,7 @@ struct ImGuiTableSettings
#endif // #ifdef IMGUI_HAS_TABLE
//-----------------------------------------------------------------------------
// [SECTION] Internal API
// [SECTION] ImGui internal API
// No guarantee of forward compatibility here!
//-----------------------------------------------------------------------------
@ -2131,7 +2180,7 @@ namespace ImGui
IMGUI_API ImGuiWindow* FindWindowByID(ImGuiID id);
IMGUI_API ImGuiWindow* FindWindowByName(const char* name);
IMGUI_API void UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags flags, ImGuiWindow* parent_window);
IMGUI_API ImVec2 CalcWindowExpectedSize(ImGuiWindow* window);
IMGUI_API ImVec2 CalcWindowNextAutoFitSize(ImGuiWindow* window);
IMGUI_API bool IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent);
IMGUI_API bool IsWindowAbove(ImGuiWindow* potential_above, ImGuiWindow* potential_below);
IMGUI_API bool IsWindowNavFocusable(ImGuiWindow* window);
@ -2151,7 +2200,9 @@ namespace ImGui
// Fonts, drawing
IMGUI_API void SetCurrentFont(ImFont* font);
inline ImFont* GetDefaultFont() { ImGuiContext& g = *GImGui; return g.IO.FontDefault ? g.IO.FontDefault : g.IO.Fonts->Fonts[0]; }
inline ImDrawList* GetForegroundDrawList(ImGuiWindow* window) { IM_UNUSED(window); ImGuiContext& g = *GImGui; return &g.ForegroundDrawList; } // This seemingly unnecessary wrapper simplifies compatibility between the 'master' and 'docking' branches.
inline ImDrawList* GetForegroundDrawList(ImGuiWindow* window) { IM_UNUSED(window); return GetForegroundDrawList(); } // This seemingly unnecessary wrapper simplifies compatibility between the 'master' and 'docking' branches.
IMGUI_API ImDrawList* GetBackgroundDrawList(ImGuiViewport* viewport); // get background draw list for the given viewport. this draw list will be the first rendering one. Useful to quickly draw shapes/text behind dear imgui contents.
IMGUI_API ImDrawList* GetForegroundDrawList(ImGuiViewport* viewport); // get foreground draw list for the given viewport. this draw list will be the last rendered one. Useful to quickly draw shapes/text over dear imgui contents.
// Init
IMGUI_API void Initialize(ImGuiContext* context);
@ -2164,7 +2215,8 @@ namespace ImGui
IMGUI_API void UpdateMouseMovingWindowEndFrame();
// Generic context hooks
IMGUI_API void AddContextHook(ImGuiContext* context, const ImGuiContextHook* hook);
IMGUI_API ImGuiID AddContextHook(ImGuiContext* context, const ImGuiContextHook* hook);
IMGUI_API void RemoveContextHook(ImGuiContext* context, ImGuiID hook_to_remove);
IMGUI_API void CallContextHooks(ImGuiContext* context, ImGuiContextHookType type);
// Settings
@ -2221,6 +2273,8 @@ namespace ImGui
// Logging/Capture
IMGUI_API void LogBegin(ImGuiLogType type, int auto_open_depth); // -> BeginCapture() when we design v2 api, for now stay under the radar by using the old name.
IMGUI_API void LogToBuffer(int auto_open_depth = -1); // Start logging/capturing to internal buffer
IMGUI_API void LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end = NULL);
IMGUI_API void LogSetNextTextDecoration(const char* prefix, const char* suffix);
// Popups, Modals, Tooltips
IMGUI_API bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags flags);
@ -2257,6 +2311,7 @@ namespace ImGui
// Inputs
// FIXME: Eventually we should aim to move e.g. IsActiveIdUsingKey() into IsKeyXXX functions.
IMGUI_API void SetItemUsingMouseWheel();
inline bool IsActiveIdUsingNavDir(ImGuiDir dir) { ImGuiContext& g = *GImGui; return (g.ActiveIdUsingNavDirMask & (1 << dir)) != 0; }
inline bool IsActiveIdUsingNavInput(ImGuiNavInput input) { ImGuiContext& g = *GImGui; return (g.ActiveIdUsingNavInputMask & (1 << input)) != 0; }
inline bool IsActiveIdUsingKey(ImGuiKey key) { ImGuiContext& g = *GImGui; IM_ASSERT(key < 64); return (g.ActiveIdUsingKeyInputMask & ((ImU64)1 << key)) != 0; }
@ -2285,8 +2340,8 @@ namespace ImGui
// Tables: Candidates for public API
IMGUI_API void TableOpenContextMenu(int column_n = -1);
IMGUI_API void TableSetColumnEnabled(int column_n, bool enabled);
IMGUI_API void TableSetColumnWidth(int column_n, float width);
IMGUI_API void TableSetColumnIsEnabled(int column_n, bool enabled);
IMGUI_API void TableSetColumnSortDirection(int column_n, ImGuiSortDirection sort_direction, bool append_to_sort_specs);
IMGUI_API int TableGetHoveredColumn(); // May use (TableGetColumnFlags() & ImGuiTableColumnFlags_IsHovered) instead. Return hovered column. return -1 when table is not hovered. return columns_count if the unused space at the right of visible columns is hovered.
IMGUI_API float TableGetHeaderRowHeight();
@ -2301,12 +2356,15 @@ namespace ImGui
IMGUI_API void TableSetupDrawChannels(ImGuiTable* table);
IMGUI_API void TableUpdateLayout(ImGuiTable* table);
IMGUI_API void TableUpdateBorders(ImGuiTable* table);
IMGUI_API void TableUpdateColumnsWeightFromWidth(ImGuiTable* table);
IMGUI_API void TableDrawBorders(ImGuiTable* table);
IMGUI_API void TableDrawContextMenu(ImGuiTable* table);
IMGUI_API void TableMergeDrawChannels(ImGuiTable* table);
IMGUI_API void TableSortSpecsSanitize(ImGuiTable* table);
IMGUI_API void TableSortSpecsBuild(ImGuiTable* table);
IMGUI_API void TableFixColumnSortDirection(ImGuiTableColumn* column);
IMGUI_API ImGuiSortDirection TableGetColumnNextSortDirection(ImGuiTableColumn* column);
IMGUI_API void TableFixColumnSortDirection(ImGuiTable* table, ImGuiTableColumn* column);
IMGUI_API float TableGetColumnWidthAuto(ImGuiTable* table, ImGuiTableColumn* column);
IMGUI_API void TableBeginRow(ImGuiTable* table);
IMGUI_API void TableEndRow(ImGuiTable* table);
IMGUI_API void TableBeginCell(ImGuiTable* table, int column_n);
@ -2314,6 +2372,7 @@ namespace ImGui
IMGUI_API ImRect TableGetCellBgRect(const ImGuiTable* table, int column_n);
IMGUI_API const char* TableGetColumnName(const ImGuiTable* table, int column_n);
IMGUI_API ImGuiID TableGetColumnResizeID(const ImGuiTable* table, int column_n, int instance_no = 0);
IMGUI_API float TableGetMaxColumnWidth(const ImGuiTable* table, int column_n);
IMGUI_API void TableSetColumnWidthAutoSingle(ImGuiTable* table, int column_n);
IMGUI_API void TableSetColumnWidthAutoAll(ImGuiTable* table);
IMGUI_API void TableRemove(ImGuiTable* table);
@ -2354,7 +2413,6 @@ namespace ImGui
IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, ImVec2 grid_off, float rounding = 0.0f, int rounding_corners_flags = ~0);
IMGUI_API void RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFlags flags = ImGuiNavHighlightFlags_TypeDefault); // Navigation highlight
IMGUI_API const char* FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text.
IMGUI_API void LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end = NULL);
// Render helpers (those functions don't access any ImGui state!)
IMGUI_API void RenderArrow(ImDrawList* draw_list, ImVec2 pos, ImU32 col, ImGuiDir dir, float scale = 1.0f);
@ -2384,6 +2442,8 @@ namespace ImGui
IMGUI_API ImGuiID GetWindowScrollbarID(ImGuiWindow* window, ImGuiAxis axis);
IMGUI_API ImGuiID GetWindowResizeID(ImGuiWindow* window, int n); // 0..3: corners, 4..7: borders
IMGUI_API void SeparatorEx(ImGuiSeparatorFlags flags);
IMGUI_API bool CheckboxFlags(const char* label, ImS64* flags, ImS64 flags_value);
IMGUI_API bool CheckboxFlags(const char* label, ImU64* flags, ImU64 flags_value);
// Widgets low-level behaviors
IMGUI_API bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0);
@ -2443,7 +2503,7 @@ namespace ImGui
IMGUI_API void DebugNodeColumns(ImGuiOldColumns* columns);
IMGUI_API void DebugNodeDrawList(ImGuiWindow* window, const ImDrawList* draw_list, const char* label);
IMGUI_API void DebugNodeDrawCmdShowMeshAndBoundingBox(ImGuiWindow* window, const ImDrawList* draw_list, const ImDrawCmd* draw_cmd, bool show_mesh, bool show_aabb);
IMGUI_API void DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList* out_draw_list, const ImDrawList* draw_list, const ImDrawCmd* draw_cmd, bool show_mesh, bool show_aabb);
IMGUI_API void DebugNodeStorage(ImGuiStorage* storage, const char* label);
IMGUI_API void DebugNodeTabBar(ImGuiTabBar* tab_bar, const char* label);
IMGUI_API void DebugNodeTable(ImGuiTable* table);
@ -2451,18 +2511,32 @@ namespace ImGui
IMGUI_API void DebugNodeWindow(ImGuiWindow* window, const char* label);
IMGUI_API void DebugNodeWindowSettings(ImGuiWindowSettings* settings);
IMGUI_API void DebugNodeWindowsList(ImVector<ImGuiWindow*>* windows, const char* label);
IMGUI_API void DebugNodeViewport(ImGuiViewportP* viewport);
IMGUI_API void DebugRenderViewportThumbnail(ImDrawList* draw_list, ImGuiViewportP* viewport, const ImRect& bb);
} // namespace ImGui
// ImFontAtlas internals
IMGUI_API bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildInit(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent);
IMGUI_API void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opaque);
IMGUI_API void ImFontAtlasBuildFinish(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildRender1bppRectFromString(ImFontAtlas* atlas, int atlas_x, int atlas_y, int w, int h, const char* in_str, char in_marker_char, unsigned char in_marker_pixel_value);
IMGUI_API void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_multiply_factor);
IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride);
//-----------------------------------------------------------------------------
// [SECTION] ImFontAtlas internal API
//-----------------------------------------------------------------------------
// This structure is likely to evolve as we add support for incremental atlas updates
struct ImFontBuilderIO
{
bool (*FontBuilder_Build)(ImFontAtlas* atlas);
};
// Helper for font builder
IMGUI_API const ImFontBuilderIO* ImFontAtlasGetBuilderForStbTruetype();
IMGUI_API void ImFontAtlasBuildInit(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent);
IMGUI_API void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opaque);
IMGUI_API void ImFontAtlasBuildFinish(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildRender8bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned char in_marker_pixel_value);
IMGUI_API void ImFontAtlasBuildRender32bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned int in_marker_pixel_value);
IMGUI_API void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_multiply_factor);
IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride);
//-----------------------------------------------------------------------------
// [SECTION] Test Engine specific hooks (imgui_test_engine)

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
// dear imgui, v1.80 WIP
// dear imgui, v1.81
// (widgets code)
/*
@ -86,6 +86,10 @@ Index of this file:
// Data
//-------------------------------------------------------------------------
// Widgets
static const float DRAGDROP_HOLD_TO_OPEN_TIMER = 0.70f; // Time for drag-hold to activate items accepting the ImGuiButtonFlags_PressedOnDragDropHold button behavior.
static const float DRAG_MOUSE_THRESHOLD_FACTOR = 0.50f; // Multiplier for the default value of io.MouseDragThreshold to make DragFloat/DragInt react faster to mouse drags.
// Those MIN/MAX values are not define because we need to point to them
static const signed char IM_S8_MIN = -128;
static const signed char IM_S8_MAX = 127;
@ -516,10 +520,9 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
if (g.DragDropActive && (flags & ImGuiButtonFlags_PressedOnDragDropHold) && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoHoldToOpenOthers))
if (IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem))
{
const float DRAG_DROP_HOLD_TIMER = 0.70f;
hovered = true;
SetHoveredID(id);
if (CalcTypematicRepeatAmount(g.HoveredIdTimer + 0.0001f - g.IO.DeltaTime, g.HoveredIdTimer + 0.0001f, DRAG_DROP_HOLD_TIMER, 0.00f))
if (CalcTypematicRepeatAmount(g.HoveredIdTimer + 0.0001f - g.IO.DeltaTime, g.HoveredIdTimer + 0.0001f, DRAGDROP_HOLD_TO_OPEN_TIMER, 0.00f))
{
pressed = true;
g.DragDropHoldJustPressedId = id;
@ -689,6 +692,9 @@ bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags
const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
RenderNavHighlight(bb, id);
RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding);
if (g.LogEnabled)
LogSetNextTextDecoration("[", "]");
RenderTextClipped(bb.Min + style.FramePadding, bb.Max - style.FramePadding, label, NULL, &label_size, style.ButtonTextAlign, &bb);
// Automatically close popups
@ -1063,7 +1069,10 @@ bool ImGui::Checkbox(const char* label, bool* v)
const ImRect total_bb(pos, pos + ImVec2(square_sz + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), label_size.y + style.FramePadding.y * 2.0f));
ItemSize(total_bb, style.FramePadding.y);
if (!ItemAdd(total_bb, id))
{
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0));
return false;
}
bool hovered, held;
bool pressed = ButtonBehavior(total_bb, id, &hovered, &held);
@ -1091,10 +1100,11 @@ bool ImGui::Checkbox(const char* label, bool* v)
RenderCheckMark(window->DrawList, check_bb.Min + ImVec2(pad, pad), check_col, square_sz - pad * 2.0f);
}
ImVec2 label_pos = ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y);
if (g.LogEnabled)
LogRenderedText(&total_bb.Min, mixed_value ? "[~]" : *v ? "[x]" : "[ ]");
LogRenderedText(&label_pos, mixed_value ? "[~]" : *v ? "[x]" : "[ ]");
if (label_size.x > 0.0f)
RenderText(ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y), label);
RenderText(label_pos, label);
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0));
return pressed;
@ -1139,6 +1149,16 @@ bool ImGui::CheckboxFlags(const char* label, unsigned int* flags, unsigned int f
return CheckboxFlagsT(label, flags, flags_value);
}
bool ImGui::CheckboxFlags(const char* label, ImS64* flags, ImS64 flags_value)
{
return CheckboxFlagsT(label, flags, flags_value);
}
bool ImGui::CheckboxFlags(const char* label, ImU64* flags, ImU64 flags_value)
{
return CheckboxFlagsT(label, flags, flags_value);
}
bool ImGui::RadioButton(const char* label, bool active)
{
ImGuiWindow* window = GetCurrentWindow();
@ -1182,10 +1202,11 @@ bool ImGui::RadioButton(const char* label, bool active)
window->DrawList->AddCircle(center, radius, GetColorU32(ImGuiCol_Border), 16, style.FrameBorderSize);
}
ImVec2 label_pos = ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y);
if (g.LogEnabled)
LogRenderedText(&total_bb.Min, active ? "(x)" : "( )");
LogRenderedText(&label_pos, active ? "(x)" : "( )");
if (label_size.x > 0.0f)
RenderText(ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y), label);
RenderText(label_pos, label);
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags);
return pressed;
@ -1369,7 +1390,8 @@ void ImGui::SeparatorEx(ImGuiSeparatorFlags flags)
// Draw
window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x, bb.Min.y), GetColorU32(ImGuiCol_Separator));
if (g.LogEnabled)
LogRenderedText(&bb.Min, "--------------------------------");
LogRenderedText(&bb.Min, "--------------------------------\n");
}
if (columns)
{
@ -1560,7 +1582,12 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
}
RenderFrameBorder(frame_bb.Min, frame_bb.Max, style.FrameRounding);
if (preview_value != NULL && !(flags & ImGuiComboFlags_NoPreview))
RenderTextClipped(frame_bb.Min + style.FramePadding, ImVec2(value_x2, frame_bb.Max.y), preview_value, NULL, NULL, ImVec2(0.0f, 0.0f));
{
ImVec2 preview_pos = frame_bb.Min + style.FramePadding;
if (g.LogEnabled)
LogSetNextTextDecoration("{", "}");
RenderTextClipped(preview_pos, ImVec2(value_x2, frame_bb.Max.y), preview_value, NULL, NULL, ImVec2(0.0f, 0.0f));
}
if (label_size.x > 0)
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
@ -1601,7 +1628,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
if (popup_window->WasActive)
{
// Always override 'AutoPosLastDirection' to not leave a chance for a past value to affect us.
ImVec2 size_expected = CalcWindowExpectedSize(popup_window);
ImVec2 size_expected = CalcWindowNextAutoFitSize(popup_window);
if (flags & ImGuiComboFlags_PopupAlignLeft)
popup_window->AutoPosLastDirection = ImGuiDir_Left; // "Below, Toward Left"
else
@ -1700,6 +1727,9 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
}
EndCombo();
if (value_changed)
MarkItemEdited(g.CurrentWindow->DC.LastItemId);
return value_changed;
}
@ -2092,7 +2122,7 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const
// Inputs accumulates into g.DragCurrentAccum, which is flushed into the current value as soon as it makes a difference with our precision settings
float adjust_delta = 0.0f;
if (g.ActiveIdSource == ImGuiInputSource_Mouse && IsMousePosValid() && g.IO.MouseDragMaxDistanceSqr[0] > 1.0f * 1.0f)
if (g.ActiveIdSource == ImGuiInputSource_Mouse && IsMousePosValid() && IsMouseDragPastThreshold(0, g.IO.MouseDragThreshold * DRAG_MOUSE_THRESHOLD_FACTOR))
{
adjust_delta = g.IO.MouseDelta[axis];
if (g.IO.KeyAlt)
@ -2255,7 +2285,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
else if (data_type == ImGuiDataType_S32 && strcmp(format, "%d") != 0) // (FIXME-LEGACY: Patch old "%.0f" format string to use "%d", read function more details.)
format = PatchFormatStringFloatToInt(format);
// Tabbing or CTRL-clicking on Drag turns it into an input box
// Tabbing or CTRL-clicking on Drag turns it into an InputText
const bool hovered = ItemHoverable(frame_bb, id);
const bool temp_input_allowed = (flags & ImGuiSliderFlags_NoInput) == 0;
bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
@ -2276,6 +2306,15 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
FocusableItemUnregister(window);
}
}
// Experimental: simple click (without moving) turns Drag into an InputText
// FIXME: Currently polling ImGuiConfigFlags_IsTouchScreen, may either poll an hypothetical ImGuiBackendFlags_HasKeyboard and/or an explicit drag settings.
if (g.IO.ConfigDragClickToInputText && temp_input_allowed && !temp_input_is_active)
if (g.ActiveId == id && hovered && g.IO.MouseReleased[0] && !IsMouseDragPastThreshold(0, g.IO.MouseDragThreshold * DRAG_MOUSE_THRESHOLD_FACTOR))
{
g.NavInputId = id;
temp_input_is_active = true;
FocusableItemUnregister(window);
}
}
if (temp_input_is_active)
@ -2298,6 +2337,8 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
char value_buf[64];
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format);
if (g.LogEnabled)
LogSetNextTextDecoration("{", "}");
RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
if (label_size.x > 0.0f)
@ -2561,7 +2602,7 @@ template<typename TYPE, typename SIGNEDTYPE, typename FLOATTYPE>
TYPE ImGui::ScaleValueFromRatioT(ImGuiDataType data_type, float t, TYPE v_min, TYPE v_max, bool is_logarithmic, float logarithmic_zero_epsilon, float zero_deadzone_halfsize)
{
if (v_min == v_max)
return (TYPE)0.0f;
return v_min;
const bool is_decimal = (data_type == ImGuiDataType_Float) || (data_type == ImGuiDataType_Double);
TYPE result;
@ -2910,6 +2951,8 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
char value_buf[64];
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format);
if (g.LogEnabled)
LogSetNextTextDecoration("{", "}");
RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
if (label_size.x > 0.0f)
@ -3825,9 +3868,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
PushStyleColor(ImGuiCol_ChildBg, style.Colors[ImGuiCol_FrameBg]);
PushStyleVar(ImGuiStyleVar_ChildRounding, style.FrameRounding);
PushStyleVar(ImGuiStyleVar_ChildBorderSize, style.FrameBorderSize);
PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding);
bool child_visible = BeginChildEx(label, id, frame_bb.GetSize(), true, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysUseWindowPadding);
PopStyleVar(3);
bool child_visible = BeginChildEx(label, id, frame_bb.GetSize(), true, ImGuiWindowFlags_NoMove);
PopStyleVar(2);
PopStyleColor();
if (!child_visible)
{
@ -3837,6 +3879,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
}
draw_window = g.CurrentWindow; // Child window
draw_window->DC.NavLayerActiveMaskNext |= (1 << draw_window->DC.NavLayerCurrent); // This is to ensure that EndChild() will display a navigation highlight so we can "enter" into it.
draw_window->DC.CursorPos += style.FramePadding;
inner_size.x -= draw_window->ScrollbarSizes.x;
}
else
@ -3997,7 +4040,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
// Edit in progress
const float mouse_x = (io.MousePos.x - frame_bb.Min.x - style.FramePadding.x) + state->ScrollX;
const float mouse_y = (is_multiline ? (io.MousePos.y - draw_window->DC.CursorPos.y - style.FramePadding.y) : (g.FontSize * 0.5f));
const float mouse_y = (is_multiline ? (io.MousePos.y - draw_window->DC.CursorPos.y) : (g.FontSize * 0.5f));
const bool is_osx = io.ConfigMacOSXBehaviors;
if (select_all || (hovered && !is_osx && io.MouseDoubleClicked[0]))
@ -4446,10 +4489,11 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
if (!(flags & ImGuiInputTextFlags_NoHorizontalScroll))
{
const float scroll_increment_x = inner_size.x * 0.25f;
const float visible_width = inner_size.x - style.FramePadding.x;
if (cursor_offset.x < state->ScrollX)
state->ScrollX = IM_FLOOR(ImMax(0.0f, cursor_offset.x - scroll_increment_x));
else if (cursor_offset.x - inner_size.x >= state->ScrollX)
state->ScrollX = IM_FLOOR(cursor_offset.x - inner_size.x + scroll_increment_x);
else if (cursor_offset.x - visible_width >= state->ScrollX)
state->ScrollX = IM_FLOOR(cursor_offset.x - visible_width + scroll_increment_x);
}
else
{
@ -4554,14 +4598,17 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
if (is_multiline)
{
Dummy(text_size);
Dummy(ImVec2(text_size.x, text_size.y + style.FramePadding.y));
EndChild();
EndGroup();
}
// Log as text
if (g.LogEnabled && (!is_password || is_displaying_hint))
{
LogSetNextTextDecoration("{", "}");
LogRenderedText(&draw_pos, buf_display, buf_display_end);
}
if (label_size.x > 0)
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
@ -5768,19 +5815,10 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
text_pos.x -= text_offset_x;
if (flags & ImGuiTreeNodeFlags_ClipLabelForTrailingButton)
frame_bb.Max.x -= g.FontSize + style.FramePadding.x;
if (g.LogEnabled)
{
// NB: '##' is normally used to hide text (as a library-wide feature), so we need to specify the text range to make sure the ## aren't stripped out here.
const char log_prefix[] = "\n##";
const char log_suffix[] = "##";
LogRenderedText(&text_pos, log_prefix, log_prefix + 3);
RenderTextClipped(text_pos, frame_bb.Max, label, label_end, &label_size);
LogRenderedText(&text_pos, log_suffix, log_suffix + 2);
}
else
{
RenderTextClipped(text_pos, frame_bb.Max, label, label_end, &label_size);
}
LogSetNextTextDecoration("###", "###");
RenderTextClipped(text_pos, frame_bb.Max, label, label_end, &label_size);
}
else
{
@ -5796,7 +5834,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
else if (!is_leaf)
RenderArrow(window->DrawList, ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y + g.FontSize * 0.15f), text_col, is_open ? ImGuiDir_Down : ImGuiDir_Right, 0.70f);
if (g.LogEnabled)
LogRenderedText(&text_pos, ">");
LogSetNextTextDecoration(">", NULL);
RenderText(text_pos, label, label_end, false);
}
@ -5882,21 +5920,25 @@ bool ImGui::CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags)
return TreeNodeBehavior(window->GetID(label), flags | ImGuiTreeNodeFlags_CollapsingHeader, label);
}
bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags flags)
// p_visible == NULL : regular collapsing header
// p_visible != NULL && *p_visible == true : show a small close button on the corner of the header, clicking the button will set *p_visible = false
// p_visible != NULL && *p_visible == false : do not show the header at all
// Do not mistake this with the Open state of the header itself, which you can adjust with SetNextItemOpen() or ImGuiTreeNodeFlags_DefaultOpen.
bool ImGui::CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFlags flags)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
return false;
if (p_open && !*p_open)
if (p_visible && !*p_visible)
return false;
ImGuiID id = window->GetID(label);
flags |= ImGuiTreeNodeFlags_CollapsingHeader;
if (p_open)
if (p_visible)
flags |= ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_ClipLabelForTrailingButton;
bool is_open = TreeNodeBehavior(id, flags, label);
if (p_open != NULL)
if (p_visible != NULL)
{
// Create a small overlapping close button
// FIXME: We can evolve this into user accessible helpers to add extra buttons on title bars, headers, etc.
@ -5908,7 +5950,7 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags
float button_y = window->DC.LastItemRect.Min.y;
ImGuiID close_button_id = GetIDWithSeed("#CLOSE", NULL, id);
if (CloseButton(close_button_id, ImVec2(button_x, button_y)))
*p_open = false;
*p_visible = false;
last_item_backup.Restore();
}
@ -5943,7 +5985,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
ItemSize(size, 0.0f);
// Fill horizontal space
// We don't support (size < 0.0f) in Selectable() because the ItemSpacing extension would make explicitely right-aligned sizes not visibly match other widgets.
// We don't support (size < 0.0f) in Selectable() because the ItemSpacing extension would make explicitly right-aligned sizes not visibly match other widgets.
const bool span_all_columns = (flags & ImGuiSelectableFlags_SpanAllColumns) != 0;
const float min_x = span_all_columns ? window->ParentWorkRect.Min.x : pos.x;
const float max_x = span_all_columns ? window->ParentWorkRect.Max.x : window->WorkRect.Max.x;
@ -6082,18 +6124,14 @@ bool ImGui::Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags
//-------------------------------------------------------------------------
// [SECTION] Widgets: ListBox
//-------------------------------------------------------------------------
// - BeginListBox()
// - EndListBox()
// - ListBox()
// - ListBoxHeader()
// - ListBoxFooter()
//-------------------------------------------------------------------------
// FIXME: This is an old API. We should redesign some of it, rename ListBoxHeader->BeginListBox, ListBoxFooter->EndListBox
// and promote using them over existing ListBox() functions, similarly to change with combo boxes.
//-------------------------------------------------------------------------
// FIXME: In principle this function should be called BeginListBox(). We should rename it after re-evaluating if we want to keep the same signature.
// Helper to calculate the size of a listbox and display a label on the right.
// Tip: To have a list filling the entire window width, PushItemWidth(-1) and pass an non-visible label e.g. "##empty"
bool ImGui::ListBoxHeader(const char* label, const ImVec2& size_arg)
// Tip: To have a list filling the entire window width, use size.x = -FLT_MIN and pass an non-visible label e.g. "##empty"
// Tip: If your vertical size is calculated from an item count (e.g. 10 * item_height) consider adding a fractional part to facilitate seeing scrolling boundaries (e.g. 10.25 * item_height).
bool ImGui::BeginListBox(const char* label, const ImVec2& size_arg)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
@ -6104,12 +6142,12 @@ bool ImGui::ListBoxHeader(const char* label, const ImVec2& size_arg)
const ImGuiID id = GetID(label);
const ImVec2 label_size = CalcTextSize(label, NULL, true);
// Size default to hold ~7 items. Fractional number of items helps seeing that we can scroll down/up without looking at scrollbar.
ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), GetTextLineHeightWithSpacing() * 7.4f + style.ItemSpacing.y);
// Size default to hold ~7.25 items.
// Fractional number of items helps seeing that we can scroll down/up without looking at scrollbar.
ImVec2 size = ImFloor(CalcItemSize(size_arg, CalcItemWidth(), GetTextLineHeightWithSpacing() * 7.25f + style.FramePadding.y * 2.0f));
ImVec2 frame_size = ImVec2(size.x, ImMax(size.y, label_size.y));
ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size);
ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
window->DC.LastItemRect = bb; // Forward storage for ListBoxFooter.. dodgy.
g.NextItemData.ClearFlags();
if (!IsRectVisible(bb.Min, bb.Max))
@ -6119,48 +6157,41 @@ bool ImGui::ListBoxHeader(const char* label, const ImVec2& size_arg)
return false;
}
// FIXME-OPT: We could omit the BeginGroup() if label_size.x but would need to omit the EndGroup() as well.
BeginGroup();
if (label_size.x > 0)
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
if (label_size.x > 0.0f)
{
ImVec2 label_pos = ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y);
RenderText(label_pos, label);
window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, label_pos + label_size);
}
BeginChildFrame(id, frame_bb.GetSize());
return true;
}
// FIXME: In principle this function should be called EndListBox(). We should rename it after re-evaluating if we want to keep the same signature.
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
// OBSOLETED in 1.81 (from February 2021)
bool ImGui::ListBoxHeader(const char* label, int items_count, int height_in_items)
{
// Size default to hold ~7.25 items.
// We add +25% worth of item height to allow the user to see at a glance if there are more items up/down, without looking at the scrollbar.
// We don't add this extra bit if items_count <= height_in_items. It is slightly dodgy, because it means a dynamic list of items will make the widget resize occasionally when it crosses that size.
// I am expecting that someone will come and complain about this behavior in a remote future, then we can advise on a better solution.
if (height_in_items < 0)
height_in_items = ImMin(items_count, 7);
const ImGuiStyle& style = GetStyle();
float height_in_items_f = (height_in_items < items_count) ? (height_in_items + 0.25f) : (height_in_items + 0.00f);
// We include ItemSpacing.y so that a list sized for the exact number of items doesn't make a scrollbar appears. We could also enforce that by passing a flag to BeginChild().
// If height_in_items == -1, default height is maximum 7.
ImGuiContext& g = *GImGui;
float height_in_items_f = (height_in_items < 0 ? ImMin(items_count, 7) : height_in_items) + 0.25f;
ImVec2 size;
size.x = 0.0f;
size.y = ImFloor(GetTextLineHeightWithSpacing() * height_in_items_f + style.FramePadding.y * 2.0f);
return ListBoxHeader(label, size);
size.y = GetTextLineHeightWithSpacing() * height_in_items_f + g.Style.FramePadding.y * 2.0f;
return BeginListBox(label, size);
}
#endif
// FIXME: In principle this function should be called EndListBox(). We should rename it after re-evaluating if we want to keep the same signature.
void ImGui::ListBoxFooter()
void ImGui::EndListBox()
{
ImGuiWindow* parent_window = GetCurrentWindow()->ParentWindow;
const ImRect bb = parent_window->DC.LastItemRect;
const ImGuiStyle& style = GetStyle();
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
IM_ASSERT((window->Flags & ImGuiWindowFlags_ChildWindow) && "Mismatched BeginListBox/EndListBox calls. Did you test the return value of BeginListBox?");
EndChildFrame();
// Redeclare item size so that it includes the label (we have stored the full size in LastItemRect)
// We call SameLine() to restore DC.CurrentLine* data
SameLine();
parent_window->DC.CursorPos = bb.Min;
ItemSize(bb, style.FramePadding.y);
EndGroup();
EndGroup(); // This is only required to be able to do IsItemXXX query on the whole ListBox including label
}
bool ImGui::ListBox(const char* label, int* current_item, const char* const items[], int items_count, int height_items)
@ -6169,25 +6200,35 @@ bool ImGui::ListBox(const char* label, int* current_item, const char* const item
return value_changed;
}
// This is merely a helper around BeginListBox(), EndListBox().
// Considering using those directly to submit custom data or store selection differently.
bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(void*, int, const char**), void* data, int items_count, int height_in_items)
{
if (!ListBoxHeader(label, items_count, height_in_items))
ImGuiContext& g = *GImGui;
// Calculate size from "height_in_items"
if (height_in_items < 0)
height_in_items = ImMin(items_count, 7);
float height_in_items_f = height_in_items + 0.25f;
ImVec2 size(0.0f, ImFloor(GetTextLineHeightWithSpacing() * height_in_items_f + g.Style.FramePadding.y * 2.0f));
if (!BeginListBox(label, size))
return false;
// Assume all items have even height (= 1 line of text). If you need items of different or variable sizes you can create a custom version of ListBox() in your code without using the clipper.
ImGuiContext& g = *GImGui;
// Assume all items have even height (= 1 line of text). If you need items of different height,
// you can create a custom version of ListBox() in your code without using the clipper.
bool value_changed = false;
ImGuiListClipper clipper;
clipper.Begin(items_count, GetTextLineHeightWithSpacing()); // We know exactly our line height here so we pass it as a minor optimization, but generally you don't need to.
while (clipper.Step())
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
{
const bool item_selected = (i == *current_item);
const char* item_text;
if (!items_getter(data, i, &item_text))
item_text = "*Unknown item*";
PushID(i);
const bool item_selected = (i == *current_item);
if (Selectable(item_text, item_selected))
{
*current_item = i;
@ -6197,7 +6238,7 @@ bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(v
SetItemDefaultFocus();
PopID();
}
ListBoxFooter();
EndListBox();
if (value_changed)
MarkItemEdited(g.CurrentWindow->DC.LastItemId);
@ -6211,6 +6252,11 @@ bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(v
// - PlotLines()
// - PlotHistogram()
//-------------------------------------------------------------------------
// Plot/Graph widgets are not very good.
// Consider writing your own, or using a third-party one, see:
// - ImPlot https://github.com/epezent/implot
// - others https://github.com/ocornut/imgui/wiki/Useful-Widgets
//-------------------------------------------------------------------------
int ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 frame_size)
{
@ -6474,7 +6520,7 @@ bool ImGui::BeginMenuBar()
clip_rect.ClipWith(window->OuterRectClipped);
PushClipRect(clip_rect.Min, clip_rect.Max, false);
// We overwrite CursorMaxPos because BeginGroup sets it to CursorPos (essentially the .EmitItem hack in EndMenuBar() would need something analoguous here, maybe a BeginGroupEx() with flags).
// We overwrite CursorMaxPos because BeginGroup sets it to CursorPos (essentially the .EmitItem hack in EndMenuBar() would need something analogous here, maybe a BeginGroupEx() with flags).
window->DC.CursorPos = window->DC.CursorMaxPos = ImVec2(bar_rect.Min.x + window->DC.MenuBarOffset.x, bar_rect.Min.y + window->DC.MenuBarOffset.y);
window->DC.LayoutType = ImGuiLayoutType_Horizontal;
window->DC.NavLayerCurrent = ImGuiNavLayer_Menu;
@ -6523,18 +6569,39 @@ void ImGui::EndMenuBar()
window->DC.MenuBarAppending = false;
}
// For the main menu bar, which cannot be moved, we honor g.Style.DisplaySafeAreaPadding to ensure text can be visible on a TV set.
bool ImGui::BeginMainMenuBar()
{
ImGuiContext& g = *GImGui;
ImGuiViewportP* viewport = (ImGuiViewportP*)(void*)GetMainViewport();
ImGuiWindow* menu_bar_window = FindWindowByName("##MainMenuBar");
// For the main menu bar, which cannot be moved, we honor g.Style.DisplaySafeAreaPadding to ensure text can be visible on a TV set.
g.NextWindowData.MenuBarOffsetMinVal = ImVec2(g.Style.DisplaySafeAreaPadding.x, ImMax(g.Style.DisplaySafeAreaPadding.y - g.Style.FramePadding.y, 0.0f));
SetNextWindowPos(ImVec2(0.0f, 0.0f));
SetNextWindowSize(ImVec2(g.IO.DisplaySize.x, g.NextWindowData.MenuBarOffsetMinVal.y + g.FontBaseSize + g.Style.FramePadding.y));
// Get our rectangle at the top of the work area
if (menu_bar_window == NULL || menu_bar_window->BeginCount == 0)
{
// Set window position
// We don't attempt to calculate our height ahead, as it depends on the per-viewport font size.
// However menu-bar will affect the minimum window size so we'll get the right height.
ImVec2 menu_bar_pos = viewport->Pos + viewport->CurrWorkOffsetMin;
ImVec2 menu_bar_size = ImVec2(viewport->Size.x - viewport->CurrWorkOffsetMin.x + viewport->CurrWorkOffsetMax.x, 1.0f);
SetNextWindowPos(menu_bar_pos);
SetNextWindowSize(menu_bar_size);
}
// Create window
PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(0, 0));
PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(0, 0)); // Lift normal size constraint, however the presence of a menu-bar will give us the minimum height we want.
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_MenuBar;
bool is_open = Begin("##MainMenuBar", NULL, window_flags) && BeginMenuBar();
PopStyleVar(2);
// Report our size into work area (for next frame) using actual window size
menu_bar_window = GetCurrentWindow();
if (menu_bar_window->BeginCount == 1)
viewport->CurrWorkOffsetMin.y += menu_bar_window->Size.y;
g.NextWindowData.MenuBarOffsetMinVal = ImVec2(0.0f, 0.0f);
if (!is_open)
{
@ -6710,7 +6777,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
if (menu_is_open)
{
SetNextWindowPos(popup_pos, ImGuiCond_Always);
SetNextWindowPos(popup_pos, ImGuiCond_Always); // Note: this is super misleading! The value will serve as reference for FindBestWindowPosForPopup(), not actual pos.
menu_is_open = BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
}
else
@ -7214,7 +7281,8 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
// Actual layout in host window (we don't do it in BeginTabBar() so as not to waste an extra frame)
ImGuiWindow* window = g.CurrentWindow;
window->DC.CursorPos = tab_bar->BarRect.Min;
ItemSize(ImVec2(tab_bar->WidthAllTabsIdeal, tab_bar->BarRect.GetHeight()), tab_bar->FramePadding.y);
ItemSize(ImVec2(tab_bar->WidthAllTabs, tab_bar->BarRect.GetHeight()), tab_bar->FramePadding.y);
window->DC.IdealMaxPos.x = ImMax(window->DC.IdealMaxPos.x, tab_bar->BarRect.Min.x + tab_bar->WidthAllTabsIdeal);
}
// Dockables uses Name/ID in the global namespace. Non-dockable items use the ID stack.
@ -7664,7 +7732,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
hovered |= (g.HoveredId == id);
// Allow the close button to overlap unless we are dragging (in which case we don't want any overlapping tabs to be hovered)
if (!held)
if (g.ActiveId != id)
SetItemAllowOverlap();
// Drag and drop: re-order tabs

View File

@ -4302,7 +4302,7 @@ static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex
int winding = 0;
orig[0] = x;
//orig[1] = y; // [DEAR IMGUI] commmented double assignment
//orig[1] = y; // [DEAR IMGUI] commented double assignment
// make sure y never passes through a vertex of the shape
y_frac = (float) STBTT_fmod(y, 1.0f);

View File

@ -1,132 +1,30 @@
# imgui_freetype
Build font atlases using FreeType instead of stb_truetype (which is the default font rasterizer in Dear ImGui).
Build font atlases using FreeType instead of stb_truetype (which is the default font rasterizer).
<br>by @vuhdo, @mikesart, @ocornut.
### Usage
1. Get latest FreeType binaries or build yourself (under Windows you may use vcpkg with `vcpkg install freetype`, `vcpkg integrate install`).
2. Add imgui_freetype.h/cpp alongside your imgui sources.
3. Include imgui_freetype.h after imgui.h.
4. Call `ImGuiFreeType::BuildFontAtlas()` *BEFORE* calling `ImFontAtlas::GetTexDataAsRGBA32()` or `ImFontAtlas::Build()` (so normal Build() won't be called):
2. Add imgui_freetype.h/cpp alongside your project files.
3. Add `#define IMGUI_ENABLE_FREETYPE` in your [imconfig.h](https://github.com/ocornut/imgui/blob/master/imconfig.h) file
```cpp
// See ImGuiFreeType::RasterizationFlags
unsigned int flags = ImGuiFreeType::NoHinting;
ImGuiFreeType::BuildFontAtlas(io.Fonts, flags);
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
```
### Gamma Correct Blending
### About Gamma Correct Blending
FreeType assumes blending in linear space rather than gamma space.
See FreeType note for [FT_Render_Glyph](https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Render_Glyph).
For correct results you need to be using sRGB and convert to linear space in the pixel shader output.
The default Dear ImGui styles will be impacted by this change (alpha values will need tweaking).
### Test code Usage
```cpp
#include "misc/freetype/imgui_freetype.h"
#include "misc/freetype/imgui_freetype.cpp"
### Testbed for toying with settings (for developers)
// Load various small fonts
ImGuiIO& io = ImGui::GetIO();
io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 13.0f);
io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 13.0f);
io.Fonts->AddFontDefault();
FreeTypeTest freetype_test;
// Main Loop
while (true)
{
if (freetype_test.UpdateRebuild())
{
// REUPLOAD FONT TEXTURE TO GPU
ImGui_ImplXXX_DestroyDeviceObjects();
ImGui_ImplXXX_CreateDeviceObjects();
}
ImGui::NewFrame();
freetype_test.ShowFreetypeOptionsWindow();
...
}
```
### Test code
```cpp
#include "misc/freetype/imgui_freetype.h"
#include "misc/freetype/imgui_freetype.cpp"
struct FreeTypeTest
{
enum FontBuildMode
{
FontBuildMode_FreeType,
FontBuildMode_Stb
};
FontBuildMode BuildMode;
bool WantRebuild;
float FontsMultiply;
int FontsPadding;
unsigned int FontsFlags;
FreeTypeTest()
{
BuildMode = FontBuildMode_FreeType;
WantRebuild = true;
FontsMultiply = 1.0f;
FontsPadding = 1;
FontsFlags = 0;
}
// Call _BEFORE_ NewFrame()
bool UpdateRebuild()
{
if (!WantRebuild)
return false;
ImGuiIO& io = ImGui::GetIO();
io.Fonts->TexGlyphPadding = FontsPadding;
for (int n = 0; n < io.Fonts->ConfigData.Size; n++)
{
ImFontConfig* font_config = (ImFontConfig*)&io.Fonts->ConfigData[n];
font_config->RasterizerMultiply = FontsMultiply;
font_config->RasterizerFlags = (BuildMode == FontBuildMode_FreeType) ? FontsFlags : 0x00;
}
if (BuildMode == FontBuildMode_FreeType)
ImGuiFreeType::BuildFontAtlas(io.Fonts, FontsFlags);
else if (BuildMode == FontBuildMode_Stb)
io.Fonts->Build();
WantRebuild = false;
return true;
}
// Call to draw interface
void ShowFreetypeOptionsWindow()
{
ImGui::Begin("FreeType Options");
ImGui::ShowFontSelector("Fonts");
WantRebuild |= ImGui::RadioButton("FreeType", (int*)&BuildMode, FontBuildMode_FreeType);
ImGui::SameLine();
WantRebuild |= ImGui::RadioButton("Stb (Default)", (int*)&BuildMode, FontBuildMode_Stb);
WantRebuild |= ImGui::DragFloat("Multiply", &FontsMultiply, 0.001f, 0.0f, 2.0f);
WantRebuild |= ImGui::DragInt("Padding", &FontsPadding, 0.1f, 0, 16);
if (BuildMode == FontBuildMode_FreeType)
{
WantRebuild |= ImGui::CheckboxFlags("NoHinting", &FontsFlags, ImGuiFreeType::NoHinting);
WantRebuild |= ImGui::CheckboxFlags("NoAutoHint", &FontsFlags, ImGuiFreeType::NoAutoHint);
WantRebuild |= ImGui::CheckboxFlags("ForceAutoHint", &FontsFlags, ImGuiFreeType::ForceAutoHint);
WantRebuild |= ImGui::CheckboxFlags("LightHinting", &FontsFlags, ImGuiFreeType::LightHinting);
WantRebuild |= ImGui::CheckboxFlags("MonoHinting", &FontsFlags, ImGuiFreeType::MonoHinting);
WantRebuild |= ImGui::CheckboxFlags("Bold", &FontsFlags, ImGuiFreeType::Bold);
WantRebuild |= ImGui::CheckboxFlags("Oblique", &FontsFlags, ImGuiFreeType::Oblique);
WantRebuild |= ImGui::CheckboxFlags("Monochrome", &FontsFlags, ImGuiFreeType::Monochrome);
}
ImGui::End();
}
};
```
See https://gist.github.com/ocornut/b3a9ecf13502fd818799a452969649ad
### Known issues
- `cfg.OversampleH`, `OversampleV` are ignored (but perhaps not so necessary with this rasterizer).
- Oversampling settins are ignored but also not so much necessary with the higher quality rendering.
### Comparaison
Small, thin anti-aliased fonts are typically benefiting a lots from Freetype's hinting:
![comparing_font_rasterizers](https://user-images.githubusercontent.com/8225057/107550178-fef87f00-6bd0-11eb-8d09-e2edb2f0ccfc.gif)

View File

@ -1,25 +1,31 @@
// dear imgui: wrapper to use FreeType (instead of stb_truetype)
// dear imgui: FreeType font builder (used as a replacement for the stb_truetype builder)
// (code)
// Get latest version at https://github.com/ocornut/imgui/tree/master/misc/freetype
// Original code by @vuhdo (Aleksei Skriabin). Improvements by @mikesart. Maintained and v0.60+ by @ocornut.
// Original code by @vuhdo (Aleksei Skriabin). Improvements by @mikesart. Maintained since 2019 by @ocornut.
// Changelog:
// - v0.50: (2017/08/16) imported from https://github.com/Vuhdo/imgui_freetype into http://www.github.com/ocornut/imgui_club, updated for latest changes in ImFontAtlas, minor tweaks.
// - v0.51: (2017/08/26) cleanup, optimizations, support for ImFontConfig::RasterizerFlags, ImFontConfig::RasterizerMultiply.
// - v0.52: (2017/09/26) fixes for imgui internal changes.
// - v0.53: (2017/10/22) minor inconsequential change to match change in master (removed an unnecessary statement).
// - v0.54: (2018/01/22) fix for addition of ImFontAtlas::TexUvscale member.
// - v0.55: (2018/02/04) moved to main imgui repository (away from http://www.github.com/ocornut/imgui_club)
// - v0.56: (2018/06/08) added support for ImFontConfig::GlyphMinAdvanceX, GlyphMaxAdvanceX.
// - v0.60: (2019/01/10) re-factored to match big update in STB builder. fixed texture height waste. fixed redundant glyphs when merging. support for glyph padding.
// - v0.61: (2019/01/15) added support for imgui allocators + added FreeType only override function SetAllocatorFunctions().
// - v0.62: (2019/02/09) added RasterizerFlags::Monochrome flag to disable font anti-aliasing (combine with ::MonoHinting for best results!)
// - v0.63: (2020/06/04) fix for rare case where FT_Get_Char_Index() succeed but FT_Load_Glyph() fails.
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2021/01/28: added support for color-layered glyphs via ImGuiFreeTypeBuilderFlags_LoadColor (require Freetype 2.10+).
// 2021/01/26: simplified integration by using '#define IMGUI_ENABLE_FREETYPE'.
// renamed ImGuiFreeType::XXX flags to ImGuiFreeTypeBuilderFlags_XXX for consistency with other API. removed ImGuiFreeType::BuildFontAtlas().
// 2020/06/04: fix for rare case where FT_Get_Char_Index() succeed but FT_Load_Glyph() fails.
// 2019/02/09: added RasterizerFlags::Monochrome flag to disable font anti-aliasing (combine with ::MonoHinting for best results!)
// 2019/01/15: added support for imgui allocators + added FreeType only override function SetAllocatorFunctions().
// 2019/01/10: re-factored to match big update in STB builder. fixed texture height waste. fixed redundant glyphs when merging. support for glyph padding.
// 2018/06/08: added support for ImFontConfig::GlyphMinAdvanceX, GlyphMaxAdvanceX.
// 2018/02/04: moved to main imgui repository (away from http://www.github.com/ocornut/imgui_club)
// 2018/01/22: fix for addition of ImFontAtlas::TexUvscale member.
// 2017/10/22: minor inconsequential change to match change in master (removed an unnecessary statement).
// 2017/09/26: fixes for imgui internal changes.
// 2017/08/26: cleanup, optimizations, support for ImFontConfig::RasterizerFlags, ImFontConfig::RasterizerMultiply.
// 2017/08/16: imported from https://github.com/Vuhdo/imgui_freetype into http://www.github.com/ocornut/imgui_club, updated for latest changes in ImFontAtlas, minor tweaks.
// Gamma Correct Blending:
// FreeType assumes blending in linear space rather than gamma space.
// See https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Render_Glyph
// For correct results you need to be using sRGB and convert to linear space in the pixel shader output.
// The default imgui styles will be impacted by this change (alpha values will need tweaking).
// About Gamma Correct Blending:
// - FreeType assumes blending in linear space rather than gamma space.
// - See https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Render_Glyph
// - For correct results you need to be using sRGB and convert to linear space in the pixel shader output.
// - The default dear imgui styles will be impacted by this change (alpha values will need tweaking).
// FIXME: cfg.OversampleH, OversampleV are not supported (but perhaps not so necessary with this rasterizer).
@ -41,6 +47,23 @@
#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
#endif
//-------------------------------------------------------------------------
// Data
//-------------------------------------------------------------------------
// Default memory allocators
static void* ImGuiFreeTypeDefaultAllocFunc(size_t size, void* user_data) { IM_UNUSED(user_data); return IM_ALLOC(size); }
static void ImGuiFreeTypeDefaultFreeFunc(void* ptr, void* user_data) { IM_UNUSED(user_data); IM_FREE(ptr); }
// Current memory allocators
static void* (*GImGuiFreeTypeAllocFunc)(size_t size, void* user_data) = ImGuiFreeTypeDefaultAllocFunc;
static void (*GImGuiFreeTypeFreeFunc)(void* ptr, void* user_data) = ImGuiFreeTypeDefaultFreeFunc;
static void* GImGuiFreeTypeAllocatorUserData = NULL;
//-------------------------------------------------------------------------
// Code
//-------------------------------------------------------------------------
namespace
{
// Glyph metrics:
@ -74,7 +97,7 @@ namespace
// | |
// |------------- advanceX ----------->|
/// A structure that describe a glyph.
// A structure that describe a glyph.
struct GlyphInfo
{
int Width; // Glyph's width in pixels.
@ -82,6 +105,7 @@ namespace
FT_Int OffsetX; // The distance from the origin ("pen position") to the left of the glyph.
FT_Int OffsetY; // The distance from the origin to the top of the glyph. This is usually a value < 0.
float AdvanceX; // The distance from the origin to the origin of the next glyph. This is usually a value > 0.
bool IsColored;
};
// Font parameters and metrics.
@ -104,7 +128,7 @@ namespace
void SetPixelHeight(int pixel_height); // Change font pixel size. All following calls to RasterizeGlyph() will use this size
const FT_Glyph_Metrics* LoadGlyph(uint32_t in_codepoint);
const FT_Bitmap* RenderGlyphAndGetInfo(GlyphInfo* out_glyph_info);
void BlitGlyph(const FT_Bitmap* ft_bitmap, uint8_t* dst, uint32_t dst_pitch, unsigned char* multiply_table = NULL);
void BlitGlyph(const FT_Bitmap* ft_bitmap, uint32_t* dst, uint32_t dst_pitch, unsigned char* multiply_table = NULL);
~FreeTypeFont() { CloseFont(); }
// [Internals]
@ -118,7 +142,7 @@ namespace
// From SDL_ttf: Handy routines for converting from fixed point
#define FT_CEIL(X) (((X + 63) & -64) / 64)
bool FreeTypeFont::InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_user_flags)
bool FreeTypeFont::InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_font_builder_flags)
{
FT_Error error = FT_New_Memory_Face(ft_library, (uint8_t*)cfg.FontData, (uint32_t)cfg.FontDataSize, (uint32_t)cfg.FontNo, &Face);
if (error != 0)
@ -131,26 +155,29 @@ namespace
SetPixelHeight((uint32_t)cfg.SizePixels);
// Convert to FreeType flags (NB: Bold and Oblique are processed separately)
UserFlags = cfg.RasterizerFlags | extra_user_flags;
UserFlags = cfg.FontBuilderFlags | extra_font_builder_flags;
LoadFlags = FT_LOAD_NO_BITMAP;
if (UserFlags & ImGuiFreeType::NoHinting)
if (UserFlags & ImGuiFreeTypeBuilderFlags_NoHinting)
LoadFlags |= FT_LOAD_NO_HINTING;
if (UserFlags & ImGuiFreeType::NoAutoHint)
if (UserFlags & ImGuiFreeTypeBuilderFlags_NoAutoHint)
LoadFlags |= FT_LOAD_NO_AUTOHINT;
if (UserFlags & ImGuiFreeType::ForceAutoHint)
if (UserFlags & ImGuiFreeTypeBuilderFlags_ForceAutoHint)
LoadFlags |= FT_LOAD_FORCE_AUTOHINT;
if (UserFlags & ImGuiFreeType::LightHinting)
if (UserFlags & ImGuiFreeTypeBuilderFlags_LightHinting)
LoadFlags |= FT_LOAD_TARGET_LIGHT;
else if (UserFlags & ImGuiFreeType::MonoHinting)
else if (UserFlags & ImGuiFreeTypeBuilderFlags_MonoHinting)
LoadFlags |= FT_LOAD_TARGET_MONO;
else
LoadFlags |= FT_LOAD_TARGET_NORMAL;
if (UserFlags & ImGuiFreeType::Monochrome)
if (UserFlags & ImGuiFreeTypeBuilderFlags_Monochrome)
RenderMode = FT_RENDER_MODE_MONO;
else
RenderMode = FT_RENDER_MODE_NORMAL;
if (UserFlags & ImGuiFreeTypeBuilderFlags_LoadColor)
LoadFlags |= FT_LOAD_COLOR;
return true;
}
@ -200,9 +227,9 @@ namespace
IM_ASSERT(slot->format == FT_GLYPH_FORMAT_OUTLINE);
// Apply convenience transform (this is not picking from real "Bold"/"Italic" fonts! Merely applying FreeType helper transform. Oblique == Slanting)
if (UserFlags & ImGuiFreeType::Bold)
if (UserFlags & ImGuiFreeTypeBuilderFlags_Bold)
FT_GlyphSlot_Embolden(slot);
if (UserFlags & ImGuiFreeType::Oblique)
if (UserFlags & ImGuiFreeTypeBuilderFlags_Oblique)
{
FT_GlyphSlot_Oblique(slot);
//FT_BBox bbox;
@ -227,11 +254,12 @@ namespace
out_glyph_info->OffsetX = Face->glyph->bitmap_left;
out_glyph_info->OffsetY = -Face->glyph->bitmap_top;
out_glyph_info->AdvanceX = (float)FT_CEIL(slot->advance.x);
out_glyph_info->IsColored = (ft_bitmap->pixel_mode == FT_PIXEL_MODE_BGRA);
return ft_bitmap;
}
void FreeTypeFont::BlitGlyph(const FT_Bitmap* ft_bitmap, uint8_t* dst, uint32_t dst_pitch, unsigned char* multiply_table)
void FreeTypeFont::BlitGlyph(const FT_Bitmap* ft_bitmap, uint32_t* dst, uint32_t dst_pitch, unsigned char* multiply_table)
{
IM_ASSERT(ft_bitmap != NULL);
const uint32_t w = ft_bitmap->width;
@ -246,13 +274,14 @@ namespace
if (multiply_table == NULL)
{
for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
memcpy(dst, src, w);
for (uint32_t x = 0; x < w; x++)
dst[x] = IM_COL32(255, 255, 255, src[x]);
}
else
{
for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
for (uint32_t x = 0; x < w; x++)
dst[x] = multiply_table[src[x]];
dst[x] = IM_COL32(255, 255, 255, multiply_table[src[x]]);
}
break;
}
@ -268,11 +297,38 @@ namespace
{
if ((x & 7) == 0)
bits = *bits_ptr++;
dst[x] = (bits & 0x80) ? color1 : color0;
dst[x] = IM_COL32(255, 255, 255, (bits & 0x80) ? color1 : color0);
}
}
break;
}
case FT_PIXEL_MODE_BGRA:
{
// FIXME: Converting pre-multiplied alpha to straight. Doesn't smell good.
#define DE_MULTIPLY(color, alpha) (ImU32)(255.0f * (float)color / (float)alpha + 0.5f)
if (multiply_table == NULL)
{
for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
for (uint32_t x = 0; x < w; x++)
{
uint8_t r = src[x * 4 + 2], g = src[x * 4 + 1], b = src[x * 4], a = src[x * 4 + 3];
dst[x] = IM_COL32(DE_MULTIPLY(r, a), DE_MULTIPLY(g, a), DE_MULTIPLY(b, a), a);
}
}
else
{
for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
{
for (uint32_t x = 0; x < w; x++)
{
uint8_t r = src[x * 4 + 2], g = src[x * 4 + 1], b = src[x * 4], a = src[x * 4 + 3];
dst[x] = IM_COL32(multiply_table[DE_MULTIPLY(r, a)], multiply_table[DE_MULTIPLY(g, a)], multiply_table[DE_MULTIPLY(b, a)], multiply_table[a]);
}
}
}
#undef DE_MULTIPLY
break;
}
default:
IM_ASSERT(0 && "FreeTypeFont::BlitGlyph(): Unknown bitmap pixel mode!");
}
@ -296,7 +352,9 @@ struct ImFontBuildSrcGlyphFT
{
GlyphInfo Info;
uint32_t Codepoint;
unsigned char* BitmapData; // Point within one of the dst_tmp_bitmap_buffers[] array
unsigned int* BitmapData; // Point within one of the dst_tmp_bitmap_buffers[] array
ImFontBuildSrcGlyphFT() { memset(this, 0, sizeof(*this)); }
};
struct ImFontBuildSrcDataFT
@ -320,7 +378,7 @@ struct ImFontBuildDstDataFT
ImBitVector GlyphsSet; // This is used to resolve collision when multiple sources are merged into a same destination font.
};
bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, unsigned int extra_flags)
bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, unsigned int extra_flags)
{
IM_ASSERT(atlas->ConfigData.Size > 0);
@ -334,6 +392,7 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
atlas->ClearTexData();
// Temporary storage for building
bool src_load_color = false;
ImVector<ImFontBuildSrcDataFT> src_tmp_array;
ImVector<ImFontBuildDstDataFT> dst_tmp_array;
src_tmp_array.resize(atlas->ConfigData.Size);
@ -363,6 +422,7 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
return false;
// Measure highest codepoints
src_load_color |= (cfg.FontBuilderFlags & ImGuiFreeTypeBuilderFlags_LoadColor) != 0;
ImFontBuildDstDataFT& dst_tmp = dst_tmp_array[src_tmp.DstIndex];
src_tmp.SrcRanges = cfg.GlyphRanges ? cfg.GlyphRanges : atlas->GetGlyphRangesDefault();
for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
@ -414,7 +474,6 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
if (entries_32 & ((ImU32)1 << bit_n))
{
ImFontBuildSrcGlyphFT src_glyph;
memset(&src_glyph, 0, sizeof(src_glyph));
src_glyph.Codepoint = (ImWchar)(((it - it_begin) << 5) + bit_n);
//src_glyph.GlyphIndex = 0; // FIXME-OPT: We had this info in the previous step and lost it..
src_tmp.GlyphsList.push_back(src_glyph);
@ -476,7 +535,7 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
IM_ASSERT(ft_bitmap);
// Allocate new temporary chunk if needed
const int bitmap_size_in_bytes = src_glyph.Info.Width * src_glyph.Info.Height;
const int bitmap_size_in_bytes = src_glyph.Info.Width * src_glyph.Info.Height * 4;
if (buf_bitmap_current_used_bytes + bitmap_size_in_bytes > BITMAP_BUFFERS_CHUNK_SIZE)
{
buf_bitmap_current_used_bytes = 0;
@ -484,9 +543,9 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
}
// Blit rasterized pixels to our temporary buffer and keep a pointer to it.
src_glyph.BitmapData = buf_bitmap_buffers.back() + buf_bitmap_current_used_bytes;
src_glyph.BitmapData = (unsigned int*)(buf_bitmap_buffers.back() + buf_bitmap_current_used_bytes);
buf_bitmap_current_used_bytes += bitmap_size_in_bytes;
src_tmp.Font.BlitGlyph(ft_bitmap, src_glyph.BitmapData, src_glyph.Info.Width * 1, multiply_enabled ? multiply_table : NULL);
src_tmp.Font.BlitGlyph(ft_bitmap, src_glyph.BitmapData, src_glyph.Info.Width, multiply_enabled ? multiply_table : NULL);
src_tmp.Rects[glyph_i].w = (stbrp_coord)(src_glyph.Info.Width + padding);
src_tmp.Rects[glyph_i].h = (stbrp_coord)(src_glyph.Info.Height + padding);
@ -533,8 +592,16 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
// 7. Allocate texture
atlas->TexHeight = (atlas->Flags & ImFontAtlasFlags_NoPowerOfTwoHeight) ? (atlas->TexHeight + 1) : ImUpperPowerOfTwo(atlas->TexHeight);
atlas->TexUvScale = ImVec2(1.0f / atlas->TexWidth, 1.0f / atlas->TexHeight);
atlas->TexPixelsAlpha8 = (unsigned char*)IM_ALLOC(atlas->TexWidth * atlas->TexHeight);
memset(atlas->TexPixelsAlpha8, 0, atlas->TexWidth * atlas->TexHeight);
if (src_load_color)
{
atlas->TexPixelsRGBA32 = (unsigned int*)IM_ALLOC(atlas->TexWidth * atlas->TexHeight * 4);
memset(atlas->TexPixelsRGBA32, 0, atlas->TexWidth * atlas->TexHeight * 4);
}
else
{
atlas->TexPixelsAlpha8 = (unsigned char*)IM_ALLOC(atlas->TexWidth * atlas->TexHeight);
memset(atlas->TexPixelsAlpha8, 0, atlas->TexWidth * atlas->TexHeight);
}
// 8. Copy rasterized font characters back into the main texture
// 9. Setup ImFont and glyphs for runtime
@ -574,10 +641,21 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
// Blit from temporary buffer to final texture
size_t blit_src_stride = (size_t)src_glyph.Info.Width;
size_t blit_dst_stride = (size_t)atlas->TexWidth;
unsigned char* blit_src = src_glyph.BitmapData;
unsigned char* blit_dst = atlas->TexPixelsAlpha8 + (ty * blit_dst_stride) + tx;
for (int y = info.Height; y > 0; y--, blit_dst += blit_dst_stride, blit_src += blit_src_stride)
memcpy(blit_dst, blit_src, blit_src_stride);
unsigned int* blit_src = src_glyph.BitmapData;
if (atlas->TexPixelsAlpha8 != NULL)
{
unsigned char* blit_dst = atlas->TexPixelsAlpha8 + (ty * blit_dst_stride) + tx;
for (int y = 0; y < info.Height; y++, blit_dst += blit_dst_stride, blit_src += blit_src_stride)
for (int x = 0; x < info.Width; x++)
blit_dst[x] = (unsigned char)((blit_src[x] >> IM_COL32_A_SHIFT) & 0xFF);
}
else
{
unsigned int* blit_dst = atlas->TexPixelsRGBA32 + (ty * blit_dst_stride) + tx;
for (int y = 0; y < info.Height; y++, blit_dst += blit_dst_stride, blit_src += blit_src_stride)
for (int x = 0; x < info.Width; x++)
blit_dst[x] = blit_src[x];
}
// Register glyph
float x0 = info.OffsetX + font_off_x;
@ -589,6 +667,10 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
float u1 = (tx + info.Width) / (float)atlas->TexWidth;
float v1 = (ty + info.Height) / (float)atlas->TexHeight;
dst_font->AddGlyph(&cfg, (ImWchar)src_glyph.Codepoint, x0, y0, x1, y1, u0, v0, u1, v1, info.AdvanceX);
IM_ASSERT(dst_font->Glyphs.back().Codepoint == src_glyph.Codepoint);
if (src_glyph.Info.IsColored)
dst_font->Glyphs.back().Colored = true;
}
src_tmp.Rects = NULL;
@ -605,50 +687,41 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
return true;
}
// Default memory allocators
static void* ImFreeTypeDefaultAllocFunc(size_t size, void* user_data) { IM_UNUSED(user_data); return IM_ALLOC(size); }
static void ImFreeTypeDefaultFreeFunc(void* ptr, void* user_data) { IM_UNUSED(user_data); IM_FREE(ptr); }
// Current memory allocators
static void* (*GImFreeTypeAllocFunc)(size_t size, void* user_data) = ImFreeTypeDefaultAllocFunc;
static void (*GImFreeTypeFreeFunc)(void* ptr, void* user_data) = ImFreeTypeDefaultFreeFunc;
static void* GImFreeTypeAllocatorUserData = NULL;
// FreeType memory allocation callbacks
static void* FreeType_Alloc(FT_Memory /*memory*/, long size)
{
return GImFreeTypeAllocFunc((size_t)size, GImFreeTypeAllocatorUserData);
return GImGuiFreeTypeAllocFunc((size_t)size, GImGuiFreeTypeAllocatorUserData);
}
static void FreeType_Free(FT_Memory /*memory*/, void* block)
{
GImFreeTypeFreeFunc(block, GImFreeTypeAllocatorUserData);
GImGuiFreeTypeFreeFunc(block, GImGuiFreeTypeAllocatorUserData);
}
static void* FreeType_Realloc(FT_Memory /*memory*/, long cur_size, long new_size, void* block)
{
// Implement realloc() as we don't ask user to provide it.
if (block == NULL)
return GImFreeTypeAllocFunc((size_t)new_size, GImFreeTypeAllocatorUserData);
return GImGuiFreeTypeAllocFunc((size_t)new_size, GImGuiFreeTypeAllocatorUserData);
if (new_size == 0)
{
GImFreeTypeFreeFunc(block, GImFreeTypeAllocatorUserData);
GImGuiFreeTypeFreeFunc(block, GImGuiFreeTypeAllocatorUserData);
return NULL;
}
if (new_size > cur_size)
{
void* new_block = GImFreeTypeAllocFunc((size_t)new_size, GImFreeTypeAllocatorUserData);
void* new_block = GImGuiFreeTypeAllocFunc((size_t)new_size, GImGuiFreeTypeAllocatorUserData);
memcpy(new_block, block, (size_t)cur_size);
GImFreeTypeFreeFunc(block, GImFreeTypeAllocatorUserData);
GImGuiFreeTypeFreeFunc(block, GImGuiFreeTypeAllocatorUserData);
return new_block;
}
return block;
}
bool ImGuiFreeType::BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags)
static bool ImFontAtlasBuildWithFreeType(ImFontAtlas* atlas)
{
// FreeType memory management: https://www.freetype.org/freetype2/docs/design/design-4.html
FT_MemoryRec_ memory_rec = {};
@ -666,15 +739,22 @@ bool ImGuiFreeType::BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags)
// If you don't call FT_Add_Default_Modules() the rest of code may work, but FreeType won't use our custom allocator.
FT_Add_Default_Modules(ft_library);
bool ret = ImFontAtlasBuildWithFreeType(ft_library, atlas, extra_flags);
bool ret = ImFontAtlasBuildWithFreeTypeEx(ft_library, atlas, atlas->FontBuilderFlags);
FT_Done_Library(ft_library);
return ret;
}
const ImFontBuilderIO* ImGuiFreeType::GetBuilderForFreeType()
{
static ImFontBuilderIO io;
io.FontBuilder_Build = ImFontAtlasBuildWithFreeType;
return &io;
}
void ImGuiFreeType::SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data)
{
GImFreeTypeAllocFunc = alloc_func;
GImFreeTypeFreeFunc = free_func;
GImFreeTypeAllocatorUserData = user_data;
GImGuiFreeTypeAllocFunc = alloc_func;
GImGuiFreeTypeFreeFunc = free_func;
GImGuiFreeTypeAllocatorUserData = user_data;
}

View File

@ -1,36 +1,49 @@
// dear imgui: wrapper to use FreeType (instead of stb_truetype)
// Get latest version at https://github.com/ocornut/imgui/tree/master/misc/freetype
// Original code by @Vuhdo (Aleksei Skriabin), maintained by @ocornut
// dear imgui: FreeType font builder (used as a replacement for the stb_truetype builder)
// (headers)
#pragma once
#include "imgui.h" // IMGUI_API, ImFontAtlas
#include "imgui.h" // IMGUI_API
// Forward declarations
struct ImFontAtlas;
struct ImFontBuilderIO;
// Hinting greatly impacts visuals (and glyph sizes).
// - By default, hinting is enabled and the font's native hinter is preferred over the auto-hinter.
// - When disabled, FreeType generates blurrier glyphs, more or less matches the stb_truetype.h
// - The Default hinting mode usually looks good, but may distort glyphs in an unusual way.
// - The Light hinting mode generates fuzzier glyphs but better matches Microsoft's rasterizer.
// You can set those flags globaly in ImFontAtlas::FontBuilderFlags
// You can set those flags on a per font basis in ImFontConfig::FontBuilderFlags
enum ImGuiFreeTypeBuilderFlags
{
ImGuiFreeTypeBuilderFlags_NoHinting = 1 << 0, // Disable hinting. This generally generates 'blurrier' bitmap glyphs when the glyph are rendered in any of the anti-aliased modes.
ImGuiFreeTypeBuilderFlags_NoAutoHint = 1 << 1, // Disable auto-hinter.
ImGuiFreeTypeBuilderFlags_ForceAutoHint = 1 << 2, // Indicates that the auto-hinter is preferred over the font's native hinter.
ImGuiFreeTypeBuilderFlags_LightHinting = 1 << 3, // A lighter hinting algorithm for gray-level modes. Many generated glyphs are fuzzier but better resemble their original shape. This is achieved by snapping glyphs to the pixel grid only vertically (Y-axis), as is done by Microsoft's ClearType and Adobe's proprietary font renderer. This preserves inter-glyph spacing in horizontal text.
ImGuiFreeTypeBuilderFlags_MonoHinting = 1 << 4, // Strong hinting algorithm that should only be used for monochrome output.
ImGuiFreeTypeBuilderFlags_Bold = 1 << 5, // Styling: Should we artificially embolden the font?
ImGuiFreeTypeBuilderFlags_Oblique = 1 << 6, // Styling: Should we slant the font, emulating italic style?
ImGuiFreeTypeBuilderFlags_Monochrome = 1 << 7, // Disable anti-aliasing. Combine this with MonoHinting for best results!
ImGuiFreeTypeBuilderFlags_LoadColor = 1 << 8 // Enable FreeType color-layered glyphs
};
namespace ImGuiFreeType
{
// Hinting greatly impacts visuals (and glyph sizes).
// When disabled, FreeType generates blurrier glyphs, more or less matches the stb's output.
// The Default hinting mode usually looks good, but may distort glyphs in an unusual way.
// The Light hinting mode generates fuzzier glyphs but better matches Microsoft's rasterizer.
// This is automatically assigned when using '#define IMGUI_ENABLE_FREETYPE'.
// If you need to dynamically select between multiple builders:
// - you can manually assign this builder with 'atlas->FontBuilderIO = ImGuiFreeType::GetBuilderForFreeType()'
// - prefer deep-copying this into your own ImFontBuilderIO instance if you use hot-reloading that messes up static data.
IMGUI_API const ImFontBuilderIO* GetBuilderForFreeType();
// You can set those flags on a per font basis in ImFontConfig::RasterizerFlags.
// Use the 'extra_flags' parameter of BuildFontAtlas() to force a flag on all your fonts.
enum RasterizerFlags
{
// By default, hinting is enabled and the font's native hinter is preferred over the auto-hinter.
NoHinting = 1 << 0, // Disable hinting. This generally generates 'blurrier' bitmap glyphs when the glyph are rendered in any of the anti-aliased modes.
NoAutoHint = 1 << 1, // Disable auto-hinter.
ForceAutoHint = 1 << 2, // Indicates that the auto-hinter is preferred over the font's native hinter.
LightHinting = 1 << 3, // A lighter hinting algorithm for gray-level modes. Many generated glyphs are fuzzier but better resemble their original shape. This is achieved by snapping glyphs to the pixel grid only vertically (Y-axis), as is done by Microsoft's ClearType and Adobe's proprietary font renderer. This preserves inter-glyph spacing in horizontal text.
MonoHinting = 1 << 4, // Strong hinting algorithm that should only be used for monochrome output.
Bold = 1 << 5, // Styling: Should we artificially embolden the font?
Oblique = 1 << 6, // Styling: Should we slant the font, emulating italic style?
Monochrome = 1 << 7 // Disable anti-aliasing. Combine this with MonoHinting for best results!
};
// Override allocators. By default ImGuiFreeType will use IM_ALLOC()/IM_FREE()
// However, as FreeType does lots of allocations we provide a way for the user to redirect it to a separate memory heap if desired.
IMGUI_API void SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data = NULL);
IMGUI_API bool BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags = 0);
// By default ImGuiFreeType will use IM_ALLOC()/IM_FREE().
// However, as FreeType does lots of allocations we provide a way for the user to redirect it to a separate memory heap if desired:
IMGUI_API void SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data = NULL);
// Obsolete names (will be removed soon)
// Prefer using '#define IMGUI_ENABLE_FREETYPE'
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
static inline bool BuildFontAtlas(ImFontAtlas* atlas, unsigned int flags = 0) { atlas->FontBuilderIO = GetBuilderForFreeType(); atlas->FontBuilderFlags = flags; return atlas->Build(); }
#endif
}