Compare commits

..

297 Commits
v1.47 ... v1.49

Author SHA1 Message Date
adb85d800d Version 1.49 2016-05-29 19:16:44 +02:00
9a751da136 Caving in to ignoring stupid pedantic Clang warnings for old-style-cast in header files 2016-05-29 19:14:19 +02:00
0fb51b6b4b Removed various superflous ImGui:: prefixes in internal code 2016-05-29 18:58:41 +02:00
9886c1b43d Undo modification of ContentsRegionRect.Max, too many side-effects (undo dff078365f) 2016-05-29 18:37:26 +02:00
dcef7dedce Comments (#590) 2016-05-29 18:24:02 +02:00
784e1ef053 CollapsingHeader() with close button adapt to horizontal scrolling (#600) 2016-05-29 18:12:25 +02:00
dff078365f Fix selectable/tree node not reaching right-side of contents size when horizontal scrolling is active and no explicit size is known 2016-05-29 18:08:51 +02:00
45dacbf084 Fixed GetWindowContentRegionMax() being off by ScrollSize amount when SizeExplicit is set + caching ContentsRegionRect.
Relates to horizontal scrollbar, explicit contents size
2016-05-29 17:50:23 +02:00
d5a12866fe Comments (#676, #655) 2016-05-29 14:00:35 +02:00
1483a69c11 Demo: Tree: showing how to align tree node label with current x position (#324, #581) 2016-05-28 19:30:01 +02:00
61c294bb52 Added optional Indent() Unindent() width (#324, #581) 2016-05-28 18:40:00 +02:00
a0a48f6e59 Added TreeAdvanceToLabelPos() (#581) 2016-05-28 18:15:54 +02:00
793f5f8cdb Comments 2016-05-28 17:54:40 +02:00
806a146198 TreeNodeEx(): ImGuiTreeNodeFlags_AlwaysOpen->ImGuiTreeNodeFlags_Leaf, + added ImGuiTreeNodeFlags_Bullet (#324, #581) 2016-05-28 17:12:13 +02:00
2acb61e3a1 Comments 2016-05-28 16:52:59 +02:00
b5521a81d4 Demo: fixed multi-selection tree nodes demo to not replace selection when clicking on single-item that's already part of selection (#581) 2016-05-28 14:18:46 +02:00
8f4b123e1b SetNextWindowSizeConstraint -> SetNextWindowSizeConstraints (#668) 2016-05-28 14:02:14 +02:00
213025f3cd BeginMenu: a menu that becomes disabled when open gets closed down, facilitate user's code (#126) 2016-05-28 11:14:02 +02:00
65b1ae6ecc Comments (#335) 2016-05-22 10:20:58 +02:00
e3d8055d90 Speculative 64-bit warning fix (#668) 2016-05-21 23:13:11 +02:00
3a776d93f2 Fixed compile issue (bloody git stashes) (#668) 2016-05-21 23:03:21 +02:00
b7ebeb1610 Added SetNextWindowSizeConstraint() + demo code (#668) 2016-05-21 22:53:08 +02:00
753bf5cefe Comments 2016-05-21 22:35:05 +02:00
713730af0c Minor sizing refactor, should be no-op. Making it a commit for further bisection since sizing code is super brittle. (#668) 2016-05-21 20:55:28 +02:00
102d03a7eb Resizing window doesn't rely on MouseDelta anymore, but rather recompute expected size based absolute mouse coords. (#668)
Storing ActiveIdClickOffset to generalize pattern already used by
columns.
2016-05-21 20:50:15 +02:00
81bf5aeb09 Minor bits 2016-05-21 20:07:51 +02:00
681d5624f7 Merge pull request #666 from jslee02/patch-1
Fix minor typo in examples/README.txt
2016-05-20 13:24:41 +02:00
47911d92b2 Fix minor typo in examples/README.txt 2016-05-20 07:04:54 -04:00
b4302187dd ImFontAtlas: Tweak to allow MergeMode to apply on a font that isn't the previous one, by setting the DstFont field. 2016-05-17 19:47:13 +02:00
1dfafeb602 CheckStacksSize() added literal strings in IM_ASSERT calls to reach end-user on common failure 2016-05-17 09:36:27 +02:00
0e51f91c5e Including limits.h again to get INT_MAX, assuming previous report of missing limits.h was erroneous (#1, yes, issue ONE!) 2016-05-16 20:27:52 +02:00
69a29e4715 Added NewLine() (very shy reminder that #97 isn't done) 2016-05-16 20:14:07 +02:00
47d10944a5 Build fix 2016-05-16 20:07:02 +02:00
787be01e61 ImGuiListClipper comments (#660, #661, #662) 2016-05-16 20:03:18 +02:00
f291f2c5dd InputText(): Fixed cursor rendering on first character when framepadding is 0.0 (following #601) 2016-05-16 19:44:03 +02:00
28b09199de ImGuiListClipper: removed assert (#662) 2016-05-16 19:25:42 +02:00
7a28f5bb81 ImGuiListClipper new version, detect height automatically, fix compatibility with SetScrollPosHere (#662) 2016-05-16 19:22:51 +02:00
fa5ae60bce Demo: added decorated label to some vertical sliders. 2016-05-16 12:05:26 +02:00
82fa628135 Merge branch 'trezanik-master' 2016-05-16 10:55:04 +02:00
1349d0aacf Examples: DirectX9: Removing spaces (#663) 2016-05-16 10:54:52 +02:00
e41fbb0390 Merge branch 'master' of https://github.com/trezanik/imgui into trezanik-master 2016-05-16 10:51:29 +02:00
790275eae2 Example: DirectX9: Backup and restore all state 2016-05-16 01:02:09 +01:00
339e191c53 Demo: Console: Add a "Scroll to bottom" button (#662) 2016-05-15 18:08:41 +02:00
9e6ed0991d Demo: clarified misleading example (#660) 2016-05-15 16:03:15 +02:00
431eaf1abe Comments to clarify what float[2] int[2] etc. are. May switch to pointers? (#659) 2016-05-14 15:35:50 +02:00
39bda5ea09 Fixed a IMGUI_API->inline case (#657, #349) 2016-05-14 10:22:25 +02:00
e79d2828c4 Metrics window: coarse clipping the detailed vertex buffer for pleasure and benefits. 2016-05-13 23:10:16 +02:00
f48f9a30ef ButtonBehavior(), fixed subtle old bug when a repeating button would also return true on release + comments (#656) 2016-05-13 11:13:54 +02:00
e1e2752dcb Fixed repeating button behavior triggering twice, typically affect the +/- of InputInt/InputFloat and user repeating buttons (#656)
+ Took note of further work
Broken in 547f34cf22
2016-05-13 10:50:59 +02:00
a2a5d71582 Demo: Tweak irritating pink color. 2016-05-12 23:13:54 +02:00
8d5b2fba95 Fixed TitleBg/TitleBgActive color being rendered above WindowBg color, being inconsistent and causing visual artefact (#655)
Broke the meaning of TitleBg and TitleBgActive. Only affect values where
Alpha<1.0f. Fixed default theme.
2016-05-12 23:12:55 +02:00
b628acbb52 StyleEditor: comments (#652) 2016-05-12 20:59:20 +02:00
10d3da6b73 Merge pull request #641 from cosmy1/errors-fix
Fix compilation errors when disabling test windows.
2016-05-12 13:41:05 +02:00
2f55dc1f33 ImFontConfig: Clarified persistence requirement of GlyphRanges array (#651) 2016-05-12 11:58:05 +02:00
ed20fcf9d5 Fixed incorrect parameter to ButtonBehavior() in Columns code - had no side-effect (#649)
Broken in 3eabad0321
2016-05-11 10:31:30 +02:00
91f11fb1bd Comments / todos 2016-05-11 09:58:43 +02:00
8648346eab Modal: fixed non-child window stacked over a modal losing its hoverabilty/focusability (#615, #604) 2016-05-10 17:02:10 +02:00
b630cb5b42 ImGuiWindow: Storing ParentWindow (#615, #646) 2016-05-10 17:00:42 +02:00
a59a04f4d0 Fixed iOS/OSX build. 2016-05-10 01:10:31 +02:00
4b5a4cae09 Fix compilation errors when disabling test windows. 2016-05-09 00:21:05 +02:00
aa11934efa Comments to clarify default shared ImFontAtlas and current context pointer thread-safety (#586, #591) 2016-05-08 17:12:54 +02:00
8a0d3b9628 Examples; DirectX10/11: Added comments about removing dependency on d3dcompiler DLL (#638) 2016-05-08 11:49:21 +02:00
382253eccf Merge branch 'master' of https://github.com/ocornut/imgui 2016-05-07 21:10:16 +02:00
36ca8a8194 Minor warnings fixes. 2016-05-07 21:09:53 +02:00
8af76d56b4 Merge pull request #639 from sergof/conversion-warnings
Ignore various anal GCC warnings.
2016-05-07 21:08:43 +02:00
2ef766a1ce Examples: DirectX10: Apply depth-stencil state like DirectX11 example (#640, #636) 2016-05-07 20:57:38 +02:00
656b1e848c Examples: DirectX11: Fixed uninitialized fields. Disabling depth-write (#640, #636) 2016-05-07 20:53:55 +02:00
f4633d09ac Examples: DirectX10, DirectX11: Removed seemingly unnecessary bunch of rasterizer state creation code. 2016-05-07 20:19:04 +02:00
834bfe4af5 Examples: DirectX11: Fixed handle leak + minor coding style fix for #640 2016-05-07 20:11:14 +02:00
1e9c9df6de Merge branch 'master' of https://github.com/josiahmanson/imgui into josiahmanson-master 2016-05-07 20:04:41 +02:00
7b9c0a5c3f Renamed ImGuiState -> ImGuiContext (#586, #269) 2016-05-07 19:55:51 +02:00
8b428e8c74 Added CreateContext/DestroyContext/GetCurrentContext/SetCurrentContext() (#586, #269) 2016-05-07 19:54:27 +02:00
5fe2cacd4d DX11 example depth test 2016-05-07 10:42:48 -07:00
6e8579fc14 Ignore implicit conversion warnings 2016-05-07 18:49:24 +02:00
69cc00f91f ImGuiStorage: Added bool helper functions for completeness. 2016-05-07 18:18:37 +02:00
ce4d731486 Minor comments, tweaks 2016-05-07 18:10:32 +02:00
313d388bba Reorganised windows moving code, documented a lag in FindHoveredWindow(), fixing lag whole moving windows (#635) 2016-05-06 11:31:32 +02:00
67df0ba185 Updated FAQ and Readme with more prominent info about WantCaptureMouse etc. flags (#635) 2016-05-06 09:18:07 +02:00
f22b6e1e09 Fixed/silenced various absurd GCC warnings from outer space (#626) 2016-05-04 23:28:16 +02:00
c1da3e354e Examples: SDL: Fixed unused variable warning on non-Windows platforms (#626) 2016-05-04 23:20:41 +02:00
79ad22e1f2 Fixed various Clang -Weverything warnings (#626) 2016-05-04 23:17:53 +02:00
efedaa5df3 Updated FAQ (#628) 2016-05-04 20:49:17 +02:00
9b79327673 BeginGroup() fixed using within Columns set (fix #630) 2016-05-04 20:22:57 +02:00
0058492156 Fonts readme, refering to IconFontCppHeaders, AddRemapChar() function, etc. 2016-05-04 17:20:11 +02:00
4ce6cf0512 Demo: Moved "Fonts" section style editor 2016-05-03 20:22:35 +02:00
f46c91f5ad Examples: DirectX9: Removed dependency on dxguid.lib + remainder of d3dx9.lib (#611) 2016-05-03 11:30:43 +02:00
731ff3d3f5 Examples: DirectX9: Removed dependency on dx3x9 (remainder) (#611) 2016-05-03 11:12:59 +02:00
50df86985d Examples: DirectX9: Removed dependency on dx3x9.h so it can be used in a DirectXMath.h only environment (#611) 2016-05-03 10:47:42 +02:00
89d5026187 Renamed majority of use of "opened" to "open" for clarity. Renamed SetNextTreeNodeOpened() to SetNextTreeNodeOpen(). (#625, #579) 2016-05-02 12:32:16 +02:00
1b9894cfb4 Merge pull request #624 from develophant/master
Fix typo in Programmer guide
2016-05-02 09:48:54 +02:00
4f34ed5010 Fix typo in Programmer guide 2016-05-01 16:18:31 -07:00
4170b4847d Style: Changed default IndentSpacing from 22 to 21 (#581, #324) 2016-05-01 23:49:10 +02:00
13df4668d1 Added GetTreeNodeToLabelSpacing() helper - tentative name (#581, #324) 2016-05-01 23:47:58 +02:00
b93040e600 TreeNode: minor tidying up (#581, #324) 2016-05-01 23:46:48 +02:00
bb674ccee6 TreeNode: added ImGuiTreeNodeFlags_AlwaysOpen flag (#581, #324) 2016-05-01 21:15:46 +02:00
9733f4fa24 Internal RenderBullet() helper. 2016-05-01 20:19:28 +02:00
f79b2d6ce3 TreeNode: added ImGuiTreeNodeFlags_OpenOnArrow flag (#581, #324, #190) 2016-05-01 20:12:14 +02:00
df764c21d6 Bullet(), BulletText(): slightly bigger. less polygons 2016-05-01 20:04:48 +02:00
470b88e965 ButtonBehavior(): ImGuiButtonFlags_PressedOnDoubleClick clears active id on double-click so that multiple flags don't trigger multiple times 2016-05-01 20:02:25 +02:00
dc8446d048 Demo: Added simple tree node selection demo (#581, #516, #190) 2016-05-01 17:55:04 +02:00
4c880b7106 Added ImGuiTreeNodeFlags_OpenOnDoubleClick (#581, #516, #190) 2016-05-01 17:46:08 +02:00
a38fd2e186 Added TreeNodeEx() functions (#581, #600, #190) 2016-05-01 17:45:31 +02:00
547f34cf22 Refactor ButtonBehavior(), fixed double-click mode also triggering on single-click (relate to #516) 2016-05-01 17:43:51 +02:00
ac501102fc Added IsItemClicked() helper (#581) 2016-05-01 17:43:17 +02:00
ec6471ca87 TreeNodeEx() wired the display-side ImGuiTreeNodeFlags_Selected flag (#581) 2016-05-01 16:06:46 +02:00
ab6bc05fc3 Fixed ImGuiTreeNodeFlags_AllowOverlapMode to behave better on touch-style inputs (#600) 2016-05-01 15:44:50 +02:00
df749e3f13 Added CollapsingHeader() variant with close button, obsoleted 4 parameters version. Refactored code into TreeNodeBehavior. (#600)
New flag and declaration makes uses of SetNextTreeNode() functions on
collapsing header more obvious as well (#579).
2016-05-01 14:34:55 +02:00
befe02559a Added IsRootWindowOrAnyChildHovered() helper (#615) 2016-05-01 12:14:07 +02:00
60d6c6d0e8 Comments/tweaks on ItemAdd() 2016-05-01 11:46:49 +02:00
bfb2dc2290 Examples: OpenGL3: Saving/restoring glActiveTexture() state (#602) 2016-04-30 19:02:19 +02:00
7406d64c64 PushClipRect(): not altering passed values, leave it to caller responsibility to floor properly (followup #582) 2016-04-30 18:55:23 +02:00
819cc414b1 Metrics window: uses IM_COL32() macro to generate constant colors. 2016-04-28 10:25:23 +02:00
c5149cd53c MenuItem(): checkmark render in disabled color when disabled 2016-04-27 23:34:24 +02:00
be7621f7c5 Updated FAQ about non UTF-8 literal (#609, #613) 2016-04-26 19:23:36 +02:00
544ba36bf6 Fixed GetFrontMostModalRootWindow() (#604) 2016-04-26 11:59:56 +02:00
ea6b615179 Made ImGui::PushClipRect()/PopClipRect() public. Changed ImDrawList::PushClipRect() prototype. Fixed demo. (#610) 2016-04-26 11:03:51 +02:00
4b6e9ac396 ImFont: Added AddRemapChar() helper (#609) 2016-04-26 10:08:06 +02:00
247da0e01b BeginGroup() comment tweaks (#608) 2016-04-25 08:45:32 +02:00
4b51e43d60 BeginGroup() extra comment because this is overused and misleading (#608) 2016-04-24 22:52:07 +02:00
919eb69931 Scrollbar: minor fix for top-right rounding of scrollbar background when window has menubar but no title bar 2016-04-24 22:38:30 +02:00
7da2d51480 MenuBar fixed missing lower border 2016-04-24 22:36:46 +02:00
a753aff07a Moved Bullet*() code below TreeNode*() code. 2016-04-24 19:38:37 +02:00
c2c0b57e5e Examples: OpenGL2: Extra comments (#606) 2016-04-24 18:11:54 +02:00
a0c411ffd2 Fixed typos in previous commit 1884f550bc (#582, #597)) 2016-04-23 14:40:43 +02:00
1884f550bc Fixed clipping rectangle floating point representation to ensure renderer-side ops yield correct results (#582, 597) 2016-04-23 14:22:41 +02:00
41215534d5 Internal ImRound() -> ImFloor(), ImRect::Round() -> ImRect::Floor(), 2016-04-23 14:10:36 +02:00
727ca4bd17 ImFont: IndexLookup stores short instead of int, so typical ascii-set lookup fits in 256 bytes 2016-04-23 11:37:18 +02:00
a20d69f9ce ImFont: Tweaking layout, shaving bit of alignment and simple hot/cot split 2016-04-23 11:29:42 +02:00
44fb99542f ImFont: RenderText() useful directly without ImDrawList::AddText().. Changed prototype. Reserving vertices after skipping non-visible lead. 2016-04-23 11:09:56 +02:00
fe73a23cf5 ImFont: Added RenderChar() helper. 2016-04-22 19:58:10 +02:00
29e259a43c InputText() clipping cursor rendering in case it gets out of the box (which can be forced w/ ImGuiInputTextFlags_NoHorizontalScroll) (#601) 2016-04-22 08:38:56 +02:00
7ce6c18bbe Refactored CloseWindowButton() into a CloseButton() helper declared in imgui_internal.h (#600) 2016-04-21 09:55:02 +02:00
559963e832 Examples: Apple/iOS: lowered xcode project deployment target from 10.7 to 10.11 (#598, #575) 2016-04-20 20:49:49 +02:00
ab4a69bcd4 Comments 2016-04-19 18:31:40 +02:00
fc3b8d0a56 Relative order of Child windows creation is preserved during sort (#595) 2016-04-19 18:31:25 +02:00
d92f1deff8 ImDrawList: Added AddQuad(), AddQuadFilled() helpers. 2016-04-18 19:04:47 +02:00
fec7dc22a9 Update README.md - binaries 2016-04-18 16:33:49 +02:00
ce61367520 Update README.md - binaries 2016-04-18 16:33:04 +02:00
af46ca2b4c Merge pull request #587 from sergof/patch-1
Fix font config propagation in FontFromMemoryCompressedTTF()
2016-04-13 09:52:34 +02:00
d5eb87d0a2 Fix font config propagation in FontFromMemoryCompressedTTF() 2016-04-13 02:01:18 +02:00
1612ca071b Examples: SDL: Initialize video+timer subsystem only. 2016-04-13 00:15:58 +02:00
006934fd15 Todo items + not using function called isblank() because it may be a macro in some C library 2016-04-12 22:36:51 +02:00
4466a7b3b0 Examples: DirectX9: save/restore some more device state. 2016-04-11 18:33:16 +02:00
1588eda1ac Version 1.49 WIP 2016-04-09 19:10:42 +02:00
95cbcdca3f Version 1.48 2016-04-09 17:46:48 +02:00
4c25de950c Warning fixes for clang. Using int64_t, may be an issue? 2016-04-09 17:46:38 +02:00
31852e1d05 Silence borderline warning with -Werror=strict-overflow
Error: assuming signed overflow does not occur when assuming that (X -
c) > X is always false [-Werror=strict-overflow]
2016-04-06 11:11:38 +02:00
319e288eef Update README.md 2016-04-05 23:08:21 +02:00
71b981d05f Examples: Apple: Readme tweaks (#575 #247) 2016-04-05 22:50:23 +02:00
b359ed7b3e Remove local glfw3 lib for osx. (+1 squashed commit)
Examples: Added OS X example (moved from ios, added support for os x)
2016-04-05 22:43:36 +02:00
67b604412b Remove local glfw3 lib for osx. (+1 squashed commit)
Squashed commits:
[34cc3b7] Adds osx example. (+6 squashed commits)
Squashed commits:
[20330f2] Uses glfw by brew install.
[0427861] Renames imguiex folder name to imguiex-ios
[f9e27e5] Renames ios_example to apple_example.
[44f8fe3] Updates the glfw header/library path.
[919f279] Renames target from imguiex to imguiex-ios since there is already a imguiex-osx target now.
[24395f5] Adds osx example.
2016-04-05 18:13:48 +08:00
2ee76bbff6 Trivial format string fix in demo 2016-04-05 09:23:00 +02:00
e808b7cfca Style: removed WindowFillAlphaDefault which was confusing and redundant, baked into WindowBg color. Renamed TooltipBg > PopupBG. (#337)
bg_alpha parameter of 5-parameters version of Begin() is an override,
however that function may become obsolete someday.
2016-04-04 01:37:02 +02:00
947171dcef Fixed InputTextMultiLine(), ListBox(), BeginChildFrame(): outer frame not honoring bordering (following #462) 2016-04-04 00:30:50 +02:00
07df3cfb3e Added ImGuiWindowFlags_AlwaysUseWindowPadding flag to ensure non-border child window uses window padding (#462) 2016-04-04 00:29:57 +02:00
8e353af1d3 Renamed ImGuiWindowFlags_Force**Scrollbar to ImGuiWindowFlags_Always**Scrollbar (#476) 2016-04-03 23:28:05 +02:00
26be1511e9 Merge branch 'Loftilus-master' 2016-04-03 17:43:40 +02:00
c1427de5b6 Examples: Libs: Update glfw binaries to glfw master. 2016-04-03 17:41:59 +02:00
0e7b9b8284 Examples: Vulkan: Coding style tweaks. 2016-04-03 17:32:53 +02:00
9c513d4443 Merge branch 'master' of https://github.com/Loftilus/imgui into Loftilus-master 2016-04-03 16:42:56 +02:00
f45fd1cef6 Comments 2016-04-03 16:42:35 +02:00
552246feed Examples: DirectX10,DirectX11 : Minor renaming 2016-04-03 13:02:04 +02:00
518f32ccfe Examples: DirectX10: Save/restore state + minor cleanups (#570) 2016-04-03 12:59:56 +02:00
90493f8add Examples: DirectX11: Shallow massaging to make the code more consistent/readable (following #570) 2016-04-03 12:48:38 +02:00
726b91a2cd Merge branch 'nlguillemot-patch-1' 2016-04-03 12:43:43 +02:00
2942240072 Examples: DX11: Cleanup state backup/restore code (#570) 2016-04-03 12:43:17 +02:00
d4d51a7802 capture and restore all state 2016-04-02 19:08:27 -07:00
650515ce49 Updated todo list and comments 2016-04-03 01:07:11 +02:00
d53c308852 Moved EndFrame() back to imgui_internal.h + comments. Undo cfbf06e394 2016-04-03 00:47:41 +02:00
1eacfd120b Update README.md 2016-04-03 00:26:00 +02:00
c61e08e8c4 InputText: move to next word OS X style behavior on OS X (#473) 2016-04-02 22:06:47 +02:00
aeaf5ccebb stb_textedit.h: proposal for upstream PR to allow custom move-left/move-right handlers (following #473) 2016-04-02 21:20:41 +02:00
9945eecaf4 stb_truetype: updated 1.08 > 1.10 + minor unused variable warning fix 2016-04-02 20:12:20 +02:00
c3376cd45c stb_textedit.h Local warning fixes 2016-04-02 20:08:42 +02:00
e7b95646b9 stb_textedit.h updated to 1.8 (our two main changes were merged now) 2016-04-02 20:08:11 +02:00
f48fc51777 IO: Added unused MultiSelectUsesSuperKey dummy field to convey semantic for OS X compatible behavior (#473) 2016-04-02 18:58:42 +02:00
aa7a29cdbf InputText(): Added io.DoubleClickSelectsWord option for OS X compatible behavior (#473) 2016-04-02 18:57:50 +02:00
587fc60f25 InputText/IO: Added WordMovementUsesAltKey , ShortcutsUseSuperKey for OS X Compatible behavior (#473) 2016-04-02 18:57:08 +02:00
a6399f120f IO: Added "Super" keyboard modifiers (corresponding to Cmd on Mac and Windows key in theory although the later is hard to read) (#473)
NB: Value not used.
2016-04-02 18:22:40 +02:00
171b0e5ca9 Update README.md 2016-03-30 16:30:17 +02:00
ae0c33c983 Examples: Links 2016-03-29 11:33:23 +02:00
41c5d4651b Update README.md 2016-03-27 12:04:17 +02:00
c4876078b4 Update README.md 2016-03-27 11:43:12 +02:00
cfbf06e394 Comments and moved EndFrame() for imgui_internal.h (for clarity? or extra confusion?) 2016-03-27 10:38:14 +02:00
39c9bb73e8 Merge pull request #563 from mneumann/fix_dragonfly
Fix compilation on DragonFly BSD
2016-03-26 16:40:00 +01:00
7661b1e778 Trim trailing spaces 2016-03-26 15:43:45 +01:00
2b7eeba143 Trim trailing spaces 2016-03-26 15:38:52 +01:00
d6750c87c2 Combo: display popup above if there's isn't enough space below / or select largest side (#505) 2016-03-25 23:36:43 +01:00
7c9fa59329 Combo: Right-most button stays highlight when popup is open. 2016-03-25 22:55:45 +01:00
c71aae08f3 Merge branch 'brushfiregames-master' 2016-03-25 22:28:19 +01:00
fdc4299c6c Examples: SDL: Made ImGui_ImplSdlGL3_NewFrame() signature match GL2 one 2016-03-25 22:27:43 +01:00
e6c2c1fcfd Examples: SDL: Minor fixes to follow syntax of other examples (#495) 2016-03-25 22:25:20 +01:00
8a61c0afea Applying same fix to OpenGL 3 example. Fixing spaces/tabs. 2016-03-25 22:20:57 +01:00
a9b0abe493 Automatically updating DisplayFrameBufferScale by reading the OpenGL drawable size and comparing with the window size. This fixed dear imgui which was rendering only to 1/4 of my window. 2016-03-25 22:19:07 +01:00
aecf5d12e6 DragFloat(), SliderFloat(), InputFloat(): fixed cases of erroneously returning true repeatedly after a text input modification (#564) 2016-03-25 21:53:59 +01:00
adb4d4d48b Fix compilation on DragonFly BSD 2016-03-24 19:37:11 +01:00
5b8aa0dc84 FAQ and comments about the use of ImTextureID (#562, #561, #521, #510, #497, #475) 2016-03-24 11:06:57 +01:00
04396ed7a9 FAQ and comments about the use of ImTextureID (#562, #561, #521, #510, #497, #475 ...) 2016-03-24 11:00:47 +01:00
367c53967f Metrics: inspect individual triangles in drawcall 2016-03-22 21:17:24 +01:00
5bed7144fe ImDrawList: Added AddTriangle() function 2016-03-22 20:10:06 +01:00
9260d46c2c Comments 2016-03-21 22:51:51 +01:00
b495a52fc0 ImDrawList: Allow AddText(ImFont* font, float font_size, ...) to take NULL/0.0f as default 2016-03-21 22:43:53 +01:00
37d50dccf9 Added GetFontTexUvWhitePixel() helper. 2016-03-21 22:30:32 +01:00
a274a09955 Renamed GetWindowFont()->GetFont(), GetWindowFontSize()->GetFontSize() (related to #340) 2016-03-21 22:29:11 +01:00
928832a5bc Various tidying up / comments, moved columns functions declarations, no functional changes 2016-03-21 22:11:43 +01:00
9cbc6e196b ImDrawList: AddRect() added optional thickness parameter + updated demo 2016-03-21 21:56:23 +01:00
86fb3a6a3c ImDrawList: AddCircle() takes optional thickness parameter 2016-03-21 21:48:05 +01:00
8e8e59a942 Merge pull request #555 from DMartinek/patch-1
CheckboxFlags: Added support for passing/testing multiple flags at the same time.
2016-03-21 13:09:55 -07:00
1bd3942b8e Merge branch 'kylawl-master' 2016-03-21 13:02:33 -07:00
feba83cfcd Merge branch 'master' of https://github.com/kylawl/imgui into kylawl-master 2016-03-21 13:02:25 -07:00
a9e303e006 Minor comments 2016-03-21 12:56:56 -07:00
b8fcb4e7e4 Converted tabs to spaces 2016-03-21 12:40:02 -07:00
3f46d9b933 Renamed FindTextDisplayEnd to FindRenderedTextEnd 2016-03-21 12:33:48 -07:00
5bffc85ba6 Exposed FindTextDisplayEnd to imgui_internal.h 2016-03-21 12:07:13 -07:00
37716184b3 Fixed coding style. 2016-03-18 16:49:19 +01:00
5abb39cb1f Added support for CheckboxFlags that can set multiple flags at the same time. 2016-03-18 14:02:14 +01:00
1394616d9c Vulkan Example: Some code layout changes. 2016-03-10 12:30:38 +01:00
4ea4fa3e73 Vulkan Example: Fix synchronization. 2016-03-10 11:59:42 +01:00
0ceddc29ff Vulkan Example: Fix windows build. 2016-03-09 17:01:38 +01:00
4cbd316f01 Vulkan example. 2016-03-09 16:39:54 +01:00
4b7edffe8a Comments 2016-03-08 20:54:21 +01:00
9ea093ddd0 DragFloat(): always apply value when mouse is held/widget active, so that can use a drag over an always-reseting value 2016-03-07 13:12:15 +01:00
1dcb9c877d Examples: OpenGL: Fix early return on zero-sized framebuffer breaking GL state (#486, #547) 2016-03-06 10:46:57 +01:00
6346690962 Comment (#544) 2016-03-04 14:09:08 +01:00
3db40903ba InputText() ImGuiInputTextFlags_CallbackAlways event set the EventFlag field of ImGuiTextEditCallbackData (#541) 2016-03-04 13:07:42 +01:00
2065cbec4d Removed extraneous comma for pedantic compilers (#516) 2016-03-03 00:34:06 +01:00
76ce08c338 Merge branch 'zapolnov-master' 2016-03-03 00:30:26 +01:00
b816d05e33 Minor tidying up following (#516) - renamed ImGuiSelectableFlags_HandleDoubleClick to ImGuiSelectableFlags_AllowDoubleClick + comments 2016-03-03 00:30:08 +01:00
6846873f23 Merge branch 'master' of https://github.com/zapolnov/imgui into zapolnov-master 2016-03-03 00:18:58 +01:00
d45044fe54 CaptureKeyboardFromApp() / CaptureMouseFromApp(): allow to enforce clearing the capture flag (#533) + demo + made code a little less messy 2016-03-03 00:09:41 +01:00
cf12bc7dea InputText: Added BufTextLen in ImGuiTextEditCallbackData. Requesting user to maintain it. Zero-ing structure properly before use. (#541) 2016-03-02 23:34:29 +01:00
17d3c202ac BeginChild()/EndChild() fixed incorrect layout to allow widgets submitted after an auto-fit child wnidow (#540) 2016-03-02 21:46:23 +01:00
ba80a457b9 Demo: plot code doesn't use ImVector to avoid heap allocation + comment (#538) 2016-02-29 12:53:05 +01:00
1881cbe860 TextUnformatted: Fixed rare crash bug with large blurb of text (2k+) not finishing with a '\n' and fully above the clipping Y line. (#535) 2016-02-24 22:43:17 +01:00
4afe67cdc8 Demo: Fixed malloc/free mismatch and leak when destructing demo console (if it has been used) (#536) 2016-02-24 11:50:21 +01:00
ab97b42935 Merge branch 'master' of https://github.com/ocornut/imgui 2016-02-21 18:10:44 +01:00
d1061c8799 Exposed FindWindowByName() in imgui_internal.h (missing chunk following 339b67c01a) 2016-02-21 18:10:35 +01:00
991d9e2884 Update README.md 2016-02-20 23:20:15 +01:00
874df53403 Update README.md 2016-02-20 20:46:08 +01:00
339b67c01a Exposed FindWindowByName() in imgui_internal.h 2016-02-20 17:37:36 +01:00
2813a44dcc Examples: OpenGL: skip rendering and calling glViewport() if we have a zero-fixed buffer (#486) 2016-02-16 09:14:38 +01:00
9e86d0e225 Examples: SDL/OpenGL: Tabs to spaces 2016-02-15 10:56:37 +01:00
87a6110994 Examples: OpenGL3: Fix BindVertexArray/BindBuffer order (#527) 2016-02-15 10:55:20 +01:00
20ba769644 Allow windows with only a callback only to be functional + minor cleanup (#524) 2016-02-14 10:33:56 +01:00
5b7a0b1b40 InputText() added comment (#526) 2016-02-11 23:00:14 +01:00
07e379a950 Examples: DirectX9: Wastefully use a RGBA8 texture for the font texture to make compability more evident with user's textures (#521) 2016-02-08 09:03:43 +01:00
dafedc3246 Demo: use locally defined strdup because compilers/standard librairies are an annoyance (#520) 2016-02-08 08:44:45 +01:00
2c6bc95dd5 Demo: InputText password demo filters out blanks (#515) 2016-02-03 09:24:57 +01:00
b329a36d27 Moved declaration of SetItemAllowOverlap() to imgui.h (ref #517) 2016-02-02 19:52:30 +01:00
a908c109c0 Added flag for selectables to handle double clicks. 2016-01-31 22:08:35 +01:00
62fe0b59bf Updated todo list 2016-01-30 18:34:19 +01:00
2efaa9a86f ImDrawList: fixed index overflow check broken by AddText(). Added extra assert. (#514) 2016-01-30 17:01:10 +01:00
a3b00b79f2 Fixed removal of trailing draw command if it is a callback command 2016-01-30 16:37:30 +01:00
b671840d15 InputTex(): Comment (#512) 2016-01-30 15:00:45 +01:00
b1ec90d565 InputText() fixed clipping bounds of contents (#512) 2016-01-30 14:57:24 +01:00
7afd62ec57 Tentative fix for GCC/Clang (#484, #504) 2016-01-25 21:45:45 +00:00
595684e08c Remove dependency on <new> header (#484, #504)
(Now expecting something to fail somewhere..)
2016-01-25 21:26:53 +00:00
3ee50af57e Fixed clipping of child windows within parent not taking account of childouter clipping boundaries (including scrollbar, etc.) (#506) 2016-01-25 20:55:34 +00:00
005b897d7d ProgressBar() handling of border size + storing border size in window structure (#503) 2016-01-24 11:00:37 +00:00
9f6b1ace8f Tidying up internal FindBestPopupWindowPos() 2016-01-23 15:13:55 +00:00
94dc3df956 ColorEdit4: Empty label doesn't add InnerSpacing, like other widgets (ref #346) 2016-01-23 14:57:48 +00:00
b6fe5eb4b4 Cleaned up the top of imgui.h, documenting all types / forward declarations 2016-01-23 12:45:56 +00:00
d5fd87e806 Added IM_COL32 macros (ref #346) 2016-01-23 12:15:49 +00:00
570a9dadc4 Honoring exact width passed to PushItemWidth(), previously it would add extra FramePadding.x*2 over that width. (ref #346)
If you had manual pixel-perfect alignment in place it might affect you.
2016-01-23 12:07:26 +00:00
8f0f71c7ba InputScalarEx(): removed unnecessary aabb computation. 2016-01-23 11:56:39 +00:00
2a505ebb9a ColorEdit4(): removed unnecessary calls to scanf() when idle in hexadecimal edit mode. 2016-01-23 11:29:22 +00:00
56927cbb54 Begin(): made the close button explicitly set the boolean to false instead of toggling it (#499) 2016-01-22 10:00:32 +00:00
13b1e0ec9b Merge branch 'master' of https://github.com/ocornut/imgui 2016-01-21 22:30:51 +00:00
b8f86ec4bd Examples: OpenGL2/3 Makefile; Added -lGL to Linux build 2016-01-21 22:30:47 +00:00
d6be992bef Travis CI: test adding osx 2016-01-21 21:43:24 +00:00
a81a5e5235 Commented Clang warning that's not compatible with all versions. Comments. 2016-01-21 21:40:22 +00:00
9e8795f4e2 Examples: Added extra comments 2016-01-21 18:51:42 +00:00
f144646c83 Merge branch 'master' of https://github.com/ocornut/imgui 2016-01-20 10:30:33 +00:00
e585204d82 ImFontAtlas: heuristic increase texture width up to 4096 with 4000+ glyphs. Various comments (#491) 2016-01-20 10:30:28 +00:00
39510d05ea Update README.md 2016-01-17 10:35:21 +00:00
3922988dea TreeNode(), CollapsingHeader() fixed not being to use "##" sequence in formatted label.
Removed DisableHideTextAfterDoubleHash hack used by Metrics window.
2016-01-16 12:25:40 +00:00
739e73b07b CalcTextSize(): adding early out for empty displayed string (#487) 2016-01-16 12:11:57 +00:00
fc66365805 Added overlooked test for label_size.x>0 before calling RenderText for label in a few instances (#487) 2016-01-16 12:01:18 +00:00
31fe006c85 Examples: DirectX10 fixed ImGui_ImplDX10_NewFrame() from recreating device objects if render isn't called (g_pVB not set) 2016-01-11 10:29:03 +00:00
6277ffe00f Examples: DirectX11: fixed ImGui_ImplDX11_NewFrame() from recreating device objects if render isn't called (g_pVB not set) 2016-01-11 10:19:38 +00:00
85725ff9c6 Added ImGuiWindowFlags_ForceVerticalScrollbar, ImGuiWindowFlags_ForceHorizontalScrollbar flags (#476) 2016-01-10 12:01:56 +00:00
76ca7c42ca ImDrawList: Added PrimQuadUV() helper to ease custom rendering of textured quads 2016-01-08 14:57:25 +00:00
bf6f6ba858 Demo: extra comments and example for PushItemWidth(-1) 2016-01-06 01:24:49 +01:00
49fb7364b5 Examples: SDL2+OpenGL3: Fix context creation options (#468, #463) 2016-01-05 10:23:43 +01:00
35085a4480 Drag*, Slider* clarified that keyboard inputs aren't clamped (#413) 2016-01-02 12:21:30 +01:00
749e8fa345 Minor optimization so that mass-calling BeginPopupContext* functions can early out more commonly without hashing ID 2015-12-31 12:11:28 +01:00
81c86dd5e7 Various minor fixes following a pass of cppcheck static analyzer 2015-12-30 11:55:37 +01:00
8061a6ceea ImVector: erase/insert uses Data/Data+Size directly. 2015-12-30 11:45:34 +01:00
4e3c6f64c0 Various minor fixes following a pass of cppcheck static analyzer 2015-12-30 11:45:13 +01:00
3aa4a108ed Examples: SDL/OpenGL3: Fixed linking documentation for MacOSX (#463) 2015-12-30 11:27:39 +01:00
40ed6a51b0 Fixed ImGuITextBuffer::empty() - unused in core lib - from being utterly broken 2015-12-30 11:07:31 +01:00
68bde7b862 Clarify comment (#455) 2015-12-27 21:41:01 +01:00
d212401624 Fixed ImDrawList::AddRect() which used to render a rectangle 1 px too large on each axis., fixed Image(), ImageButton() as well (#457) 2015-12-27 21:31:43 +01:00
6dbdc69131 ImDrawList: Fixed AddCircle() to fit precisely within bounding box like AddCircleFilled() and AddRectFilled() (followup #457 2015-12-27 20:18:43 +01:00
668a247af0 Demo: added more draw primitives in the Custom Rendering example (#457) 2015-12-27 19:49:31 +01:00
dc4a07c49a Fixed various Clang -Weverything warnings 2015-12-26 14:59:07 +01:00
e41568f87f Version number 1.48 WIP + Update binaries 2015-12-26 10:02:57 +01:00
85 changed files with 7269 additions and 3220 deletions

View File

@ -2,6 +2,7 @@ language: cpp
os: os:
- linux - linux
- osx
compiler: compiler:
- gcc - gcc

View File

@ -39,13 +39,19 @@ Demo
---- ----
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here. You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
- [imgui-demo-binaries-20150909.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20150909.zip) (Windows binaries, ImGui 1.46 WIP 2015/09/09, 4 executables, 505 KB) - [imgui-demo-binaries-20160410.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20160410.zip) (Windows binaries, ImGui 1.48+ 2016/04/10, 4 executables, 534 KB)
Gallery Gallery
------- -------
![screenshot 1](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v143/examples_04.png) See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
![screenshot 1](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/examples_01.png)
![screenshot 2](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/examples_02.png)
[![profiler](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler-880.jpg)](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
![screenshot 2](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v143/test_window_01.png) ![screenshot 2](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v143/test_window_01.png)
![screenshot 3](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v143/test_window_02.png) ![screenshot 3](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v143/test_window_02.png)
![screenshot 4](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v143/test_window_03.png) ![screenshot 4](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v143/test_window_03.png)
@ -89,12 +95,15 @@ Frequently Asked Question (FAQ)
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations. The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
<b>How do I update to a newer version of ImGui?</b> <b>How do I update to a newer version of ImGui?</b>
<br><b>Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)</b> <br><b>What is ImTextureID and how do I display an image?</b>
<br><b>I integrated ImGui in my engine and the text or lines are blurry..</b> <br><b>I integrated ImGui in my engine and the text or lines are blurry..</b>
<br><b>I integrated ImGui in my engine and some elements are disappearing when I move windows around..</b> <br><b>I integrated ImGui in my engine and some elements are disappearing when I move windows around..</b>
<br><b>How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.</b>
<br><b>How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?</b>
<br><b>How can I load a different font than the default?</b> <br><b>How can I load a different font than the default?</b>
<br><b>How can I load multiple fonts?</b> <br><b>How can I load multiple fonts?</b>
<br><b>How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?</b> <br><b>How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?</b>
<br><b>How can I use the drawing facilities without an ImGui window? (using ImDrawList API)</b>
See the FAQ in imgui.cpp for answers. See the FAQ in imgui.cpp for answers.
@ -124,6 +133,10 @@ If you intend to display large lists of items (say, 1000+) it can be beneficial
You can alter the look of the interface to some degree: changing colors, sizes, padding, rounding, fonts. However, as ImGui is designed and optimised to create debug tools, the amount of skinning you can apply is limited. There is only so much you can stray away from the default look and feel of the interface. You can alter the look of the interface to some degree: changing colors, sizes, padding, rounding, fonts. However, as ImGui is designed and optimised to create debug tools, the amount of skinning you can apply is limited. There is only so much you can stray away from the default look and feel of the interface.
This is [LumixEngine](https://github.com/nem0/LumixEngine) with a minor skinning hack + a docking/tabs extension (both of which you can find in the Issues section and will eventually be merged).
[![Skinning in LumixEngine](https://cloud.githubusercontent.com/assets/8225057/13198792/92808c5c-d812-11e5-9507-16b63918b05b.jpg)](https://cloud.githubusercontent.com/assets/8225057/13044612/59f07aec-d3cf-11e5-8ccb-39adf2e13e69.png)
<b>Why using C++ (as opposed to C)?</b> <b>Why using C++ (as opposed to C)?</b>
ImGui takes advantage of a few C++ features for convenience but nothing anywhere Boost-insanity/quagmire. In particular, function overloading and default parameters are used to make the API easier to use and code more terse. Doing so I believe the API is sitting on a sweet spot and giving up on those features would make the API more cumbersome. Other features such as namespace, constructors and templates (in the case of the ImVector<> class) are also relied on as a convenience but could be removed. ImGui takes advantage of a few C++ features for convenience but nothing anywhere Boost-insanity/quagmire. In particular, function overloading and default parameters are used to make the API easier to use and code more terse. Doing so I believe the API is sitting on a sweet spot and giving up on those features would make the API more cumbersome. Other features such as namespace, constructors and templates (in the case of the ImVector<> class) are also relied on as a convenience but could be removed.
@ -152,13 +165,16 @@ Embeds [stb_textedit.h, stb_truetype.h, stb_rectpack.h](https://github.com/nothi
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub. Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui). Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
Special supporters: Double-chocolate sponsors:
- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano. - Media Molecule, Mobigame
And: Salty caramel supporters:
- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm. - Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano, Chris Genova, ikrima
Caramel supporters:
- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley.
And other supporters; thanks! And other supporters; thanks!

View File

@ -1,5 +1,10 @@
Those are standalone ready-to-build applications to demonstrate ImGui. Those are standalone ready-to-build applications to demonstrate ImGui.
Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
(languages: C, .net, rust, D, Python, Lua..)
(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR; TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
@ -17,7 +22,7 @@ ImGui is highly portable and only requires a few things to run:
- Optional: clipboard support, mouse cursor supports, Windows IME support, etc. - Optional: clipboard support, mouse cursor supports, Windows IME support, etc.
So this is essentially what those examples are doing + the obligatory cruft for portability. So this is essentially what those examples are doing + the obligatory cruft for portability.
Unfortunately in 2015 it is still tedious to create and maintain portable build files using external Unfortunately in 2016 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 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 I choose to provide: third party software. For most examples here I choose to provide:
- Makefiles for Linux/OSX - Makefiles for Linux/OSX
@ -27,6 +32,15 @@ Please let me know if they don't work with your setup!
You can probably just import the imgui_impl_xxx.cpp/.h files into your own codebase or compile those You can probably just import the imgui_impl_xxx.cpp/.h files into your own codebase or compile those
directly with a command-line compiler. directly with a command-line compiler.
ImGui has zero frame of lag for most behaviors and one frame of lag for some behaviors.
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
opengl_example/ opengl_example/
OpenGL example, using GLFW + fixed pipeline. OpenGL example, using GLFW + fixed pipeline.
This is simple and should work for all OpenGL enabled applications. This is simple and should work for all OpenGL enabled applications.
@ -49,15 +63,15 @@ directx11_example/
DirectX11 example, Windows only. DirectX11 example, Windows only.
This is quite long and tedious, because: DirectX11. This is quite long and tedious, because: DirectX11.
ios_example/ apple_example/
iOS example. OSX & iOS example.
Using Synergy to access keyboard/mouse data from server computer. On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky. Synergy keyboard integration is rather hacky.
sdl_opengl_example/ sdl_opengl_example/
SDL2 + OpenGL example. SDL2 + OpenGL example.
sdl_opengl_example/ sdl_opengl3_example/
SDL2 + OpenGL3 example. SDL2 + OpenGL3 example.
allegro5_example/ allegro5_example/
@ -66,3 +80,7 @@ allegro5_example/
marmalade_example/ marmalade_example/
Marmalade example using IwGx Marmalade example using IwGx
vulkan_example/
Vulkan example.
This is quite long and tedious, because: Vulkan.

View File

@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings // ImGui Allegro 5 bindings
// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@ -247,6 +249,7 @@ void ImGui_ImplA5_NewFrame()
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL); io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT); io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR); io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse; ALLEGRO_MOUSE_STATE mouse;
if (keys.display == g_Display) if (keys.display == g_Display)

View File

@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings // ImGui Allegro 5 bindings
// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.

View File

@ -1,20 +1,27 @@
# iOS example # iOS / OSX example
## Introduction ## Introduction
This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device.
It is a rather complex example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy.
Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active. Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active.
## How to Use ## How to Use on iOS
0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" * In Synergy, go to Preferences, and uncheck "Use SSL encryption"
0. Run the example app. * Run the example app.
0. Tap the "servername" button in the corner * Tap the "servername" button in the corner
0. Enter the name or the IP of your synergy host * Enter the name or the IP of your synergy host
0. If you had previously connected to a server, you may need to kill and re-start the app. * If you had previously connected to a server, you may need to kill and re-start the app.
## How to Build on OSX
* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh)
* Run the command: `brew install glfw3`
* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme
* Click `Run` button
## Notes and TODOs ## Notes and TODOs
@ -25,7 +32,8 @@ Things that would be nice but I didn't get around to doing:
* Graceful disconnect/reconnect from uSynergy. * Graceful disconnect/reconnect from uSynergy.
* Copy/Paste not well-supported * Copy/Paste not well-supported
## C++ on iOS ## C++ on iOS / OSX
ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension.
Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer.

View File

@ -63,6 +63,11 @@
"idiom" : "ipad", "idiom" : "ipad",
"filename" : "icon_imgui_76@2x~ipad.png", "filename" : "icon_imgui_76@2x~ipad.png",
"scale" : "2x" "scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
} }
], ],
"info" : { "info" : {

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,22 @@
// ImGui iOS+OpenGL+Synergy binding
// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much.
// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application.
// by Joel Davis (joeld42@gmail.com)
#pragma once
#include <Foundation/Foundation.h>
#include <UIKit/UIKit.h>
@interface ImGuiHelper : NSObject
- (id) initWithView: (UIView *)view;
- (void)connectServer: (NSString*)serverName;
- (void)render;
- (void)newFrame;
@end

View File

@ -1,6 +1,7 @@
// // ImGui iOS+OpenGL+Synergy binding
// imgui_impl_ios.cpp // In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
// imguiex // Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much.
// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application.
#import <OpenGLES/ES3/gl.h> #import <OpenGLES/ES3/gl.h>
#import <OpenGLES/ES3/glext.h> #import <OpenGLES/ES3/glext.h>
@ -262,10 +263,10 @@ void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key,
// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); // printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false");
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.KeysDown[key] = down; io.KeysDown[key] = down;
io.KeyShift = modifiers & USYNERGY_MODIFIER_SHIFT; io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT);
io.KeyCtrl = modifiers & USYNERGY_MODIFIER_CTRL; io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL);
io.KeyAlt = modifiers & USYNERGY_MODIFIER_ALT; io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT);
io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN);
// Add this as keyboard input // Add this as keyboard input
if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL))

View File

@ -0,0 +1,15 @@
//
// AppDelegate.h
// imguiex-osx
//
// Created by James Chen on 4/5/16.
// Copyright © 2016 Joel Davis. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate>
@end

View File

@ -0,0 +1,26 @@
//
// AppDelegate.m
// imguiex-osx
//
// Created by James Chen on 4/5/16.
// Copyright © 2016 Joel Davis. All rights reserved.
//
#import "AppDelegate.h"
@interface AppDelegate ()
@property (weak) IBOutlet NSWindow *window;
@end
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
}
@end

View File

@ -0,0 +1,64 @@
{
"images" : [
{
"idiom" : "mac",
"size" : "16x16",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "16x16",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "32x32",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "32x32",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "128x128",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "128x128",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "256x256",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "256x256",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "512x512",
"scale" : "1x"
},
{
"size" : "512x512",
"idiom" : "mac",
"filename" : "icon_imgui_180x180.png",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "512x512",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2016 Joel Davis. All rights reserved.</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>

View File

@ -0,0 +1,13 @@
//
// main.m
// imguiex-osx
//
// Created by James Chen on 4/5/16.
// Copyright © 2016 Joel Davis. All rights reserved.
//
#import <Cocoa/Cocoa.h>
int main(int argc, const char * argv[]) {
return NSApplicationMain(argc, argv);
}

View File

@ -9,6 +9,16 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; };
197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; };
1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F221CB39FB50090F036 /* AppDelegate.m */; };
1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1A0F271CB39FB50090F036 /* Assets.xcassets */; };
1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; };
1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; };
1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; };
1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; };
1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; };
1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F391CB3A1B20090F036 /* main.cpp */; };
1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */; };
1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */; };
6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; };
6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; };
6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; };
@ -28,9 +38,18 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_draw.cpp; path = ../../imgui_draw.cpp; sourceTree = "<group>"; }; 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_draw.cpp; path = ../../imgui_draw.cpp; sourceTree = "<group>"; };
197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = "<group>"; }; 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = "<group>"; };
1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-osx.app"; sourceTree = BUILT_PRODUCTS_DIR; };
1A1A0F211CB39FB50090F036 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = "<group>"; };
1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = "<group>"; };
1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = "<absolute>"; };
6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = "<group>"; }; 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = "<group>"; };
6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = "<group>"; }; 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = "<group>"; };
6D2FC5541B2E632000C130BA /* imguiex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = imguiex.app; sourceTree = BUILT_PRODUCTS_DIR; }; 6D2FC5541B2E632000C130BA /* imguiex-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; };
6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; }; 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; }; 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
@ -54,6 +73,14 @@
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
1A1A0F1C1CB39FB50090F036 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
6D2FC5511B2E632000C130BA /* Frameworks */ = { 6D2FC5511B2E632000C130BA /* Frameworks */ = {
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -66,6 +93,38 @@
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */ /* Begin PBXGroup section */
1A1A0F201CB39FB50090F036 /* imguiex-osx */ = {
isa = PBXGroup;
children = (
1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */,
1A1A0F351CB3A1B20090F036 /* opengl_example */,
1A1A0F211CB39FB50090F036 /* AppDelegate.h */,
1A1A0F221CB39FB50090F036 /* AppDelegate.m */,
1A1A0F271CB39FB50090F036 /* Assets.xcassets */,
1A1A0F2C1CB39FB50090F036 /* Info.plist */,
1A1A0F241CB39FB50090F036 /* Supporting Files */,
);
path = "imguiex-osx";
sourceTree = "<group>";
};
1A1A0F241CB39FB50090F036 /* Supporting Files */ = {
isa = PBXGroup;
children = (
);
name = "Supporting Files";
sourceTree = "<group>";
};
1A1A0F351CB3A1B20090F036 /* opengl_example */ = {
isa = PBXGroup;
children = (
1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */,
1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */,
1A1A0F391CB3A1B20090F036 /* main.cpp */,
);
name = opengl_example;
path = ../../opengl_example;
sourceTree = "<group>";
};
6D1E39141B35EEF10017B40F /* usynergy */ = { 6D1E39141B35EEF10017B40F /* usynergy */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -81,7 +140,8 @@
children = ( children = (
6D1E39141B35EEF10017B40F /* usynergy */, 6D1E39141B35EEF10017B40F /* usynergy */,
6D2FC5841B2E648D00C130BA /* imgui */, 6D2FC5841B2E648D00C130BA /* imgui */,
6D2FC5561B2E632000C130BA /* imguiex */, 6D2FC5561B2E632000C130BA /* imguiex-ios */,
1A1A0F201CB39FB50090F036 /* imguiex-osx */,
6D2FC5551B2E632000C130BA /* Products */, 6D2FC5551B2E632000C130BA /* Products */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
@ -89,12 +149,13 @@
6D2FC5551B2E632000C130BA /* Products */ = { 6D2FC5551B2E632000C130BA /* Products */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
6D2FC5541B2E632000C130BA /* imguiex.app */, 6D2FC5541B2E632000C130BA /* imguiex-ios.app */,
1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */,
); );
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
6D2FC5561B2E632000C130BA /* imguiex */ = { 6D2FC5561B2E632000C130BA /* imguiex-ios */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */,
@ -113,7 +174,7 @@
6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */,
6D2FC5571B2E632000C130BA /* Supporting Files */, 6D2FC5571B2E632000C130BA /* Supporting Files */,
); );
path = imguiex; path = "imguiex-ios";
sourceTree = "<group>"; sourceTree = "<group>";
}; };
6D2FC5571B2E632000C130BA /* Supporting Files */ = { 6D2FC5571B2E632000C130BA /* Supporting Files */ = {
@ -141,9 +202,26 @@
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
6D2FC5531B2E632000C130BA /* imguiex */ = { 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = {
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */; buildConfigurationList = 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */;
buildPhases = (
1A1A0F1B1CB39FB50090F036 /* Sources */,
1A1A0F1C1CB39FB50090F036 /* Frameworks */,
1A1A0F1D1CB39FB50090F036 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = "imguiex-osx";
productName = "imguiex-osx";
productReference = 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */;
productType = "com.apple.product-type.application";
};
6D2FC5531B2E632000C130BA /* imguiex-ios */ = {
isa = PBXNativeTarget;
buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */;
buildPhases = ( buildPhases = (
6D2FC5501B2E632000C130BA /* Sources */, 6D2FC5501B2E632000C130BA /* Sources */,
6D2FC5511B2E632000C130BA /* Frameworks */, 6D2FC5511B2E632000C130BA /* Frameworks */,
@ -153,9 +231,9 @@
); );
dependencies = ( dependencies = (
); );
name = imguiex; name = "imguiex-ios";
productName = imguiex; productName = imguiex;
productReference = 6D2FC5541B2E632000C130BA /* imguiex.app */; productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */;
productType = "com.apple.product-type.application"; productType = "com.apple.product-type.application";
}; };
/* End PBXNativeTarget section */ /* End PBXNativeTarget section */
@ -167,6 +245,9 @@
LastUpgradeCheck = 0630; LastUpgradeCheck = 0630;
ORGANIZATIONNAME = "Joel Davis"; ORGANIZATIONNAME = "Joel Davis";
TargetAttributes = { TargetAttributes = {
1A1A0F1E1CB39FB50090F036 = {
CreatedOnToolsVersion = 7.3;
};
6D2FC5531B2E632000C130BA = { 6D2FC5531B2E632000C130BA = {
CreatedOnToolsVersion = 6.3.2; CreatedOnToolsVersion = 6.3.2;
}; };
@ -185,12 +266,21 @@
projectDirPath = ""; projectDirPath = "";
projectRoot = ""; projectRoot = "";
targets = ( targets = (
6D2FC5531B2E632000C130BA /* imguiex */, 6D2FC5531B2E632000C130BA /* imguiex-ios */,
1A1A0F1E1CB39FB50090F036 /* imguiex-osx */,
); );
}; };
/* End PBXProject section */ /* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */ /* Begin PBXResourcesBuildPhase section */
1A1A0F1D1CB39FB50090F036 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
6D2FC5521B2E632000C130BA /* Resources */ = { 6D2FC5521B2E632000C130BA /* Resources */ = {
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -206,6 +296,21 @@
/* End PBXResourcesBuildPhase section */ /* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */
1A1A0F1B1CB39FB50090F036 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */,
1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */,
1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */,
1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */,
1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */,
1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */,
1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */,
1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
6D2FC5501B2E632000C130BA /* Sources */ = { 6D2FC5501B2E632000C130BA /* Sources */ = {
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -244,6 +349,54 @@
/* End PBXVariantGroup section */ /* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */ /* Begin XCBuildConfiguration section */
1A1A0F2D1CB39FB50090F036 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ANALYZER_NONNULL = YES;
CODE_SIGN_IDENTITY = "-";
COMBINE_HIDPI_IMAGES = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_TESTABILITY = YES;
HEADER_SEARCH_PATHS = (
"$(inherited)",
"$(SRCROOT)/../../",
/usr/local/include,
);
INFOPLIST_FILE = "imguiex-osx/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
LIBRARY_SEARCH_PATHS = /usr/local/lib;
MACOSX_DEPLOYMENT_TARGET = 10.7;
PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
USER_HEADER_SEARCH_PATHS = "";
};
name = Debug;
};
1A1A0F2E1CB39FB50090F036 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ANALYZER_NONNULL = YES;
CODE_SIGN_IDENTITY = "-";
COMBINE_HIDPI_IMAGES = YES;
HEADER_SEARCH_PATHS = (
"$(inherited)",
"$(SRCROOT)/../../",
/usr/local/include,
);
INFOPLIST_FILE = "imguiex-osx/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
LIBRARY_SEARCH_PATHS = /usr/local/lib;
MACOSX_DEPLOYMENT_TARGET = 10.7;
PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
USER_HEADER_SEARCH_PATHS = "";
};
name = Release;
};
6D2FC5791B2E632000C130BA /* Debug */ = { 6D2FC5791B2E632000C130BA /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
@ -280,11 +433,13 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = "$(SRCROOT)/../../";
IPHONEOS_DEPLOYMENT_TARGET = 8.0; IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos; SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
USER_HEADER_SEARCH_PATHS = "";
}; };
name = Debug; name = Debug;
}; };
@ -318,10 +473,12 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = "$(SRCROOT)/../../";
IPHONEOS_DEPLOYMENT_TARGET = 8.0; IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
USER_HEADER_SEARCH_PATHS = "";
VALIDATE_PRODUCT = YES; VALIDATE_PRODUCT = YES;
}; };
name = Release; name = Release;
@ -330,7 +487,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = imguiex/Info.plist; INFOPLIST_FILE = "imguiex-ios/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
}; };
@ -340,7 +497,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = imguiex/Info.plist; INFOPLIST_FILE = "imguiex-ios/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
}; };
@ -349,6 +506,15 @@
/* End XCBuildConfiguration section */ /* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */ /* Begin XCConfigurationList section */
1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1A1A0F2D1CB39FB50090F036 /* Debug */,
1A1A0F2E1CB39FB50090F036 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
@ -358,7 +524,7 @@
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release; defaultConfigurationName = Release;
}; };
6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */ = { 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
6D2FC57C1B2E632000C130BA /* Debug */, 6D2FC57C1B2E632000C130BA /* Debug */,

View File

@ -1,4 +1,6 @@
// ImGui Win32 + DirectX10 binding // ImGui Win32 + DirectX10 binding
// In this binding, ImTextureID is used to store a 'ID3D10ShaderResourceView*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@ -32,6 +34,7 @@ static ID3D10SamplerState* g_pFontSampler = NULL;
static ID3D10ShaderResourceView*g_pFontTextureView = NULL; static ID3D10ShaderResourceView*g_pFontTextureView = NULL;
static ID3D10RasterizerState* g_pRasterizerState = NULL; static ID3D10RasterizerState* g_pRasterizerState = NULL;
static ID3D10BlendState* g_pBlendState = NULL; static ID3D10BlendState* g_pBlendState = NULL;
static ID3D10DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000; static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER struct VERTEX_CONSTANT_BUFFER
@ -44,6 +47,8 @@ struct VERTEX_CONSTANT_BUFFER
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
void ImGui_ImplDX10_RenderDrawLists(ImDrawData* draw_data) void ImGui_ImplDX10_RenderDrawLists(ImDrawData* draw_data)
{ {
ID3D10Device* ctx = g_pd3dDevice;
// Create and grow vertex/index buffers if needed // Create and grow vertex/index buffers if needed
if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount) if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount)
{ {
@ -56,7 +61,7 @@ void ImGui_ImplDX10_RenderDrawLists(ImDrawData* draw_data)
desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
desc.MiscFlags = 0; desc.MiscFlags = 0;
if (g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pVB) < 0) if (ctx->CreateBuffer(&desc, NULL, &g_pVB) < 0)
return; return;
} }
@ -64,13 +69,13 @@ void ImGui_ImplDX10_RenderDrawLists(ImDrawData* draw_data)
{ {
if (g_pIB) { g_pIB->Release(); g_pIB = NULL; } if (g_pIB) { g_pIB->Release(); g_pIB = NULL; }
g_IndexBufferSize = draw_data->TotalIdxCount + 10000; g_IndexBufferSize = draw_data->TotalIdxCount + 10000;
D3D10_BUFFER_DESC bufferDesc; D3D10_BUFFER_DESC desc;
memset(&bufferDesc, 0, sizeof(D3D10_BUFFER_DESC)); memset(&desc, 0, sizeof(D3D10_BUFFER_DESC));
bufferDesc.Usage = D3D10_USAGE_DYNAMIC; desc.Usage = D3D10_USAGE_DYNAMIC;
bufferDesc.ByteWidth = g_IndexBufferSize * sizeof(ImDrawIdx); desc.ByteWidth = g_IndexBufferSize * sizeof(ImDrawIdx);
bufferDesc.BindFlags = D3D10_BIND_INDEX_BUFFER; desc.BindFlags = D3D10_BIND_INDEX_BUFFER;
bufferDesc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
if (g_pd3dDevice->CreateBuffer(&bufferDesc, NULL, &g_pIB) < 0) if (ctx->CreateBuffer(&desc, NULL, &g_pIB) < 0)
return; return;
} }
@ -79,7 +84,6 @@ void ImGui_ImplDX10_RenderDrawLists(ImDrawData* draw_data)
ImDrawIdx* idx_dst = NULL; ImDrawIdx* idx_dst = NULL;
g_pVB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&vtx_dst); g_pVB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&vtx_dst);
g_pIB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&idx_dst); g_pIB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&idx_dst);
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {
const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawList* cmd_list = draw_data->CmdLists[n];
@ -93,11 +97,10 @@ void ImGui_ImplDX10_RenderDrawLists(ImDrawData* draw_data)
// Setup orthographic projection matrix into our constant buffer // Setup orthographic projection matrix into our constant buffer
{ {
void* mappedResource; void* mapped_resource;
if (g_pVertexConstantBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &mappedResource) != S_OK) if (g_pVertexConstantBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
return; return;
VERTEX_CONSTANT_BUFFER* constant_buffer = (VERTEX_CONSTANT_BUFFER*)mapped_resource;
VERTEX_CONSTANT_BUFFER* pConstantBuffer = (VERTEX_CONSTANT_BUFFER*)mappedResource;
const float L = 0.0f; const float L = 0.0f;
const float R = ImGui::GetIO().DisplaySize.x; const float R = ImGui::GetIO().DisplaySize.x;
const float B = ImGui::GetIO().DisplaySize.y; const float B = ImGui::GetIO().DisplaySize.y;
@ -109,39 +112,76 @@ void ImGui_ImplDX10_RenderDrawLists(ImDrawData* draw_data)
{ 0.0f, 0.0f, 0.5f, 0.0f }, { 0.0f, 0.0f, 0.5f, 0.0f },
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f }, { (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
}; };
memcpy(&pConstantBuffer->mvp, mvp, sizeof(mvp)); memcpy(&constant_buffer->mvp, mvp, sizeof(mvp));
g_pVertexConstantBuffer->Unmap(); g_pVertexConstantBuffer->Unmap();
} }
// Setup viewport // Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!)
struct BACKUP_DX10_STATE
{ {
UINT ScissorRectsCount, ViewportsCount;
D3D10_RECT ScissorRects[D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
D3D10_VIEWPORT Viewports[D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
ID3D10RasterizerState* RS;
ID3D10BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
UINT StencilRef;
ID3D10DepthStencilState* DepthStencilState;
ID3D10ShaderResourceView* PSShaderResource;
ID3D10SamplerState* PSSampler;
ID3D10PixelShader* PS;
ID3D10VertexShader* VS;
D3D10_PRIMITIVE_TOPOLOGY PrimitiveTopology;
ID3D10Buffer* IndexBuffer, *VertexBuffer, *VSConstantBuffer;
UINT IndexBufferOffset, VertexBufferStride, VertexBufferOffset;
DXGI_FORMAT IndexBufferFormat;
ID3D10InputLayout* InputLayout;
};
BACKUP_DX10_STATE old;
old.ScissorRectsCount = old.ViewportsCount = D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
ctx->PSGetShader(&old.PS);
ctx->VSGetShader(&old.VS);
ctx->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer);
ctx->IAGetPrimitiveTopology(&old.PrimitiveTopology);
ctx->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset);
ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
ctx->IAGetInputLayout(&old.InputLayout);
// Setup viewport
D3D10_VIEWPORT vp; D3D10_VIEWPORT vp;
memset(&vp, 0, sizeof(D3D10_VIEWPORT)); memset(&vp, 0, sizeof(D3D10_VIEWPORT));
vp.Width = (UINT)ImGui::GetIO().DisplaySize.x; vp.Width = (UINT)ImGui::GetIO().DisplaySize.x;
vp.Height = (UINT)ImGui::GetIO().DisplaySize.y; vp.Height = (UINT)ImGui::GetIO().DisplaySize.y;
vp.MinDepth = 0.0f; vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f; vp.MaxDepth = 1.0f;
vp.TopLeftX = 0; vp.TopLeftX = vp.TopLeftY = 0;
vp.TopLeftY = 0; ctx->RSSetViewports(1, &vp);
g_pd3dDevice->RSSetViewports(1, &vp);
}
// Bind shader and vertex buffers // Bind shader and vertex buffers
unsigned int stride = sizeof(ImDrawVert); unsigned int stride = sizeof(ImDrawVert);
unsigned int offset = 0; unsigned int offset = 0;
g_pd3dDevice->IASetInputLayout(g_pInputLayout); ctx->IASetInputLayout(g_pInputLayout);
g_pd3dDevice->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset); ctx->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset);
g_pd3dDevice->IASetIndexBuffer(g_pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0); ctx->IASetIndexBuffer(g_pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
g_pd3dDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST); ctx->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
g_pd3dDevice->VSSetShader(g_pVertexShader); ctx->VSSetShader(g_pVertexShader);
g_pd3dDevice->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer); ctx->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer);
g_pd3dDevice->PSSetShader(g_pPixelShader); ctx->PSSetShader(g_pPixelShader);
g_pd3dDevice->PSSetSamplers(0, 1, &g_pFontSampler); ctx->PSSetSamplers(0, 1, &g_pFontSampler);
// Setup render state // Setup render state
const float blendFactor[4] = { 0.f, 0.f, 0.f, 0.f }; const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
g_pd3dDevice->OMSetBlendState(g_pBlendState, blendFactor, 0xffffffff); ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
g_pd3dDevice->RSSetState(g_pRasterizerState); ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists // Render command lists
int vtx_offset = 0; int vtx_offset = 0;
@ -159,19 +199,30 @@ void ImGui_ImplDX10_RenderDrawLists(ImDrawData* draw_data)
else else
{ {
const D3D10_RECT r = { (LONG)pcmd->ClipRect.x, (LONG)pcmd->ClipRect.y, (LONG)pcmd->ClipRect.z, (LONG)pcmd->ClipRect.w }; const D3D10_RECT r = { (LONG)pcmd->ClipRect.x, (LONG)pcmd->ClipRect.y, (LONG)pcmd->ClipRect.z, (LONG)pcmd->ClipRect.w };
g_pd3dDevice->PSSetShaderResources(0, 1, (ID3D10ShaderResourceView**)&pcmd->TextureId); ctx->PSSetShaderResources(0, 1, (ID3D10ShaderResourceView**)&pcmd->TextureId);
g_pd3dDevice->RSSetScissorRects(1, &r); ctx->RSSetScissorRects(1, &r);
g_pd3dDevice->DrawIndexed(pcmd->ElemCount, idx_offset, vtx_offset); ctx->DrawIndexed(pcmd->ElemCount, idx_offset, vtx_offset);
} }
idx_offset += pcmd->ElemCount; idx_offset += pcmd->ElemCount;
} }
vtx_offset += cmd_list->VtxBuffer.size(); vtx_offset += cmd_list->VtxBuffer.size();
} }
// Restore modified state // Restore modified DX state
g_pd3dDevice->IASetInputLayout(NULL); ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
g_pd3dDevice->PSSetShader(NULL); ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
g_pd3dDevice->VSSetShader(NULL); ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS); if (old.PS) old.PS->Release();
ctx->VSSetShader(old.VS); if (old.VS) old.VS->Release();
ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release();
ctx->IASetPrimitiveTopology(old.PrimitiveTopology);
ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release();
ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release();
ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
} }
IMGUI_API LRESULT ImGui_ImplDX10_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) IMGUI_API LRESULT ImGui_ImplDX10_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam)
@ -232,33 +283,33 @@ static void ImGui_ImplDX10_CreateFontsTexture()
// Create DX10 texture // Create DX10 texture
{ {
D3D10_TEXTURE2D_DESC texDesc; D3D10_TEXTURE2D_DESC desc;
ZeroMemory(&texDesc, sizeof(texDesc)); ZeroMemory(&desc, sizeof(desc));
texDesc.Width = width; desc.Width = width;
texDesc.Height = height; desc.Height = height;
texDesc.MipLevels = 1; desc.MipLevels = 1;
texDesc.ArraySize = 1; desc.ArraySize = 1;
texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
texDesc.SampleDesc.Count = 1; desc.SampleDesc.Count = 1;
texDesc.Usage = D3D10_USAGE_DEFAULT; desc.Usage = D3D10_USAGE_DEFAULT;
texDesc.BindFlags = D3D10_BIND_SHADER_RESOURCE; desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
texDesc.CPUAccessFlags = 0; desc.CPUAccessFlags = 0;
ID3D10Texture2D *pTexture = NULL; ID3D10Texture2D *pTexture = NULL;
D3D10_SUBRESOURCE_DATA subResource; D3D10_SUBRESOURCE_DATA subResource;
subResource.pSysMem = pixels; subResource.pSysMem = pixels;
subResource.SysMemPitch = texDesc.Width * 4; subResource.SysMemPitch = desc.Width * 4;
subResource.SysMemSlicePitch = 0; subResource.SysMemSlicePitch = 0;
g_pd3dDevice->CreateTexture2D(&texDesc, &subResource, &pTexture); g_pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
// Create texture view // Create texture view
D3D10_SHADER_RESOURCE_VIEW_DESC srvDesc; D3D10_SHADER_RESOURCE_VIEW_DESC srv_desc;
ZeroMemory(&srvDesc, sizeof(srvDesc)); ZeroMemory(&srv_desc, sizeof(srv_desc));
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; srv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
srvDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D; srv_desc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = texDesc.MipLevels; srv_desc.Texture2D.MipLevels = desc.MipLevels;
srvDesc.Texture2D.MostDetailedMip = 0; srv_desc.Texture2D.MostDetailedMip = 0;
g_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &g_pFontTextureView); g_pd3dDevice->CreateShaderResourceView(pTexture, &srv_desc, &g_pFontTextureView);
pTexture->Release(); pTexture->Release();
} }
@ -267,17 +318,17 @@ static void ImGui_ImplDX10_CreateFontsTexture()
// Create texture sampler // Create texture sampler
{ {
D3D10_SAMPLER_DESC samplerDesc; D3D10_SAMPLER_DESC desc;
ZeroMemory(&samplerDesc, sizeof(samplerDesc)); ZeroMemory(&desc, sizeof(desc));
samplerDesc.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR; desc.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR;
samplerDesc.AddressU = D3D10_TEXTURE_ADDRESS_WRAP; desc.AddressU = D3D10_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressV = D3D10_TEXTURE_ADDRESS_WRAP; desc.AddressV = D3D10_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressW = D3D10_TEXTURE_ADDRESS_WRAP; desc.AddressW = D3D10_TEXTURE_ADDRESS_WRAP;
samplerDesc.MipLODBias = 0.f; desc.MipLODBias = 0.f;
samplerDesc.ComparisonFunc = D3D10_COMPARISON_ALWAYS; desc.ComparisonFunc = D3D10_COMPARISON_ALWAYS;
samplerDesc.MinLOD = 0.f; desc.MinLOD = 0.f;
samplerDesc.MaxLOD = 0.f; desc.MaxLOD = 0.f;
g_pd3dDevice->CreateSamplerState(&samplerDesc, &g_pFontSampler); g_pd3dDevice->CreateSamplerState(&desc, &g_pFontSampler);
} }
// Cleanup (don't clear the input data if you want to append new fonts later) // Cleanup (don't clear the input data if you want to append new fonts later)
@ -292,6 +343,12 @@ bool ImGui_ImplDX10_CreateDeviceObjects()
if (g_pFontSampler) if (g_pFontSampler)
ImGui_ImplDX10_InvalidateDeviceObjects(); ImGui_ImplDX10_InvalidateDeviceObjects();
// By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
// If you would like to use this DX11 sample code but remove this dependency you can:
// 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
// 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
// See https://github.com/ocornut/imgui/pull/638 for sources and details.
// Create the vertex shader // Create the vertex shader
{ {
static const char* vertexShader = static const char* vertexShader =
@ -329,24 +386,24 @@ bool ImGui_ImplDX10_CreateDeviceObjects()
return false; return false;
// Create the input layout // Create the input layout
D3D10_INPUT_ELEMENT_DESC localLayout[] = { D3D10_INPUT_ELEMENT_DESC local_layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->pos), D3D10_INPUT_PER_VERTEX_DATA, 0 }, { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->pos), D3D10_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->uv), D3D10_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->uv), D3D10_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D10_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D10_INPUT_PER_VERTEX_DATA, 0 },
}; };
if (g_pd3dDevice->CreateInputLayout(local_layout, 3, g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK)
if (g_pd3dDevice->CreateInputLayout(localLayout, 3, g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK)
return false; return false;
// Create the constant buffer // Create the constant buffer
{ {
D3D10_BUFFER_DESC cbDesc; D3D10_BUFFER_DESC desc;
cbDesc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER); desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER);
cbDesc.Usage = D3D10_USAGE_DYNAMIC; desc.Usage = D3D10_USAGE_DYNAMIC;
cbDesc.BindFlags = D3D10_BIND_CONSTANT_BUFFER; desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER;
cbDesc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
cbDesc.MiscFlags = 0; desc.MiscFlags = 0;
g_pd3dDevice->CreateBuffer(&cbDesc, NULL, &g_pVertexConstantBuffer); g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pVertexConstantBuffer);
} }
} }
@ -402,6 +459,20 @@ bool ImGui_ImplDX10_CreateDeviceObjects()
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState); g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
} }
// Create depth-stencil State
{
D3D10_DEPTH_STENCIL_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.DepthEnable = false;
desc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
desc.DepthFunc = D3D10_COMPARISON_ALWAYS;
desc.StencilEnable = false;
desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
desc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
desc.BackFace = desc.FrontFace;
g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
}
ImGui_ImplDX10_CreateFontsTexture(); ImGui_ImplDX10_CreateFontsTexture();
return true; return true;
@ -418,6 +489,7 @@ void ImGui_ImplDX10_InvalidateDeviceObjects()
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; } if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; } if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; } if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; } if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; } if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
@ -474,7 +546,7 @@ void ImGui_ImplDX10_Shutdown()
void ImGui_ImplDX10_NewFrame() void ImGui_ImplDX10_NewFrame()
{ {
if (!g_pVB) if (!g_pFontSampler)
ImGui_ImplDX10_CreateDeviceObjects(); ImGui_ImplDX10_CreateDeviceObjects();
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
@ -494,6 +566,7 @@ void ImGui_ImplDX10_NewFrame()
io.KeyCtrl = (GetKeyState(VK_CONTROL) & 0x8000) != 0; io.KeyCtrl = (GetKeyState(VK_CONTROL) & 0x8000) != 0;
io.KeyShift = (GetKeyState(VK_SHIFT) & 0x8000) != 0; io.KeyShift = (GetKeyState(VK_SHIFT) & 0x8000) != 0;
io.KeyAlt = (GetKeyState(VK_MENU) & 0x8000) != 0; io.KeyAlt = (GetKeyState(VK_MENU) & 0x8000) != 0;
io.KeySuper = false;
// io.KeysDown : filled by WM_KEYDOWN/WM_KEYUP events // io.KeysDown : filled by WM_KEYDOWN/WM_KEYUP events
// io.MousePos : filled by WM_MOUSEMOVE events // io.MousePos : filled by WM_MOUSEMOVE events
// io.MouseDown : filled by WM_*BUTTON* events // io.MouseDown : filled by WM_*BUTTON* events

View File

@ -1,4 +1,6 @@
// ImGui Win32 + DirectX10 binding // ImGui Win32 + DirectX10 binding
// In this binding, ImTextureID is used to store a 'ID3D10ShaderResourceView*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.

View File

@ -5,7 +5,6 @@
#include "imgui_impl_dx10.h" #include "imgui_impl_dx10.h"
#include <d3d10_1.h> #include <d3d10_1.h>
#include <d3d10.h> #include <d3d10.h>
#include <d3dcompiler.h>
#define DIRECTINPUT_VERSION 0x0800 #define DIRECTINPUT_VERSION 0x0800
#include <dinput.h> #include <dinput.h>
#include <tchar.h> #include <tchar.h>
@ -63,27 +62,6 @@ HRESULT CreateDeviceD3D(HWND hWnd)
if (D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice) != S_OK) if (D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice) != S_OK)
return E_FAIL; return E_FAIL;
// Setup rasterizer
{
D3D10_RASTERIZER_DESC RSDesc;
memset(&RSDesc, 0, sizeof(D3D10_RASTERIZER_DESC));
RSDesc.FillMode = D3D10_FILL_SOLID;
RSDesc.CullMode = D3D10_CULL_NONE;
RSDesc.FrontCounterClockwise = FALSE;
RSDesc.DepthBias = 0;
RSDesc.SlopeScaledDepthBias = 0.0f;
RSDesc.DepthBiasClamp = 0;
RSDesc.DepthClipEnable = TRUE;
RSDesc.ScissorEnable = TRUE;
RSDesc.AntialiasedLineEnable = FALSE;
RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
ID3D10RasterizerState* pRState = NULL;
g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
g_pd3dDevice->RSSetState(pRState);
pRState->Release();
}
CreateRenderTarget(); CreateRenderTarget();
return S_OK; return S_OK;

View File

@ -1,4 +1,6 @@
// ImGui Win32 + DirectX11 binding // ImGui Win32 + DirectX11 binding
// In this binding, ImTextureID is used to store a 'ID3D11ShaderResourceView*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@ -32,6 +34,7 @@ static ID3D11SamplerState* g_pFontSampler = NULL;
static ID3D11ShaderResourceView*g_pFontTextureView = NULL; static ID3D11ShaderResourceView*g_pFontTextureView = NULL;
static ID3D11RasterizerState* g_pRasterizerState = NULL; static ID3D11RasterizerState* g_pRasterizerState = NULL;
static ID3D11BlendState* g_pBlendState = NULL; static ID3D11BlendState* g_pBlendState = NULL;
static ID3D11DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000; static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER struct VERTEX_CONSTANT_BUFFER
@ -44,6 +47,8 @@ struct VERTEX_CONSTANT_BUFFER
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
void ImGui_ImplDX11_RenderDrawLists(ImDrawData* draw_data) void ImGui_ImplDX11_RenderDrawLists(ImDrawData* draw_data)
{ {
ID3D11DeviceContext* ctx = g_pd3dDeviceContext;
// Create and grow vertex/index buffers if needed // Create and grow vertex/index buffers if needed
if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount) if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount)
{ {
@ -63,21 +68,21 @@ void ImGui_ImplDX11_RenderDrawLists(ImDrawData* draw_data)
{ {
if (g_pIB) { g_pIB->Release(); g_pIB = NULL; } if (g_pIB) { g_pIB->Release(); g_pIB = NULL; }
g_IndexBufferSize = draw_data->TotalIdxCount + 10000; g_IndexBufferSize = draw_data->TotalIdxCount + 10000;
D3D11_BUFFER_DESC bufferDesc; D3D11_BUFFER_DESC desc;
memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
bufferDesc.Usage = D3D11_USAGE_DYNAMIC; desc.Usage = D3D11_USAGE_DYNAMIC;
bufferDesc.ByteWidth = g_IndexBufferSize * sizeof(ImDrawIdx); desc.ByteWidth = g_IndexBufferSize * sizeof(ImDrawIdx);
bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
if (g_pd3dDevice->CreateBuffer(&bufferDesc, NULL, &g_pIB) < 0) if (g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pIB) < 0)
return; return;
} }
// Copy and convert all vertices into a single contiguous buffer // Copy and convert all vertices into a single contiguous buffer
D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource; D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource;
if (g_pd3dDeviceContext->Map(g_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK) if (ctx->Map(g_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK)
return; return;
if (g_pd3dDeviceContext->Map(g_pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK) if (ctx->Map(g_pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK)
return; return;
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData; ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData;
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData; ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData;
@ -89,60 +94,99 @@ void ImGui_ImplDX11_RenderDrawLists(ImDrawData* draw_data)
vtx_dst += cmd_list->VtxBuffer.size(); vtx_dst += cmd_list->VtxBuffer.size();
idx_dst += cmd_list->IdxBuffer.size(); idx_dst += cmd_list->IdxBuffer.size();
} }
g_pd3dDeviceContext->Unmap(g_pVB, 0); ctx->Unmap(g_pVB, 0);
g_pd3dDeviceContext->Unmap(g_pIB, 0); ctx->Unmap(g_pIB, 0);
// Setup orthographic projection matrix into our constant buffer // Setup orthographic projection matrix into our constant buffer
{ {
D3D11_MAPPED_SUBRESOURCE mappedResource; D3D11_MAPPED_SUBRESOURCE mapped_resource;
if (g_pd3dDeviceContext->Map(g_pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource) != S_OK) if (ctx->Map(g_pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
return; return;
VERTEX_CONSTANT_BUFFER* constant_buffer = (VERTEX_CONSTANT_BUFFER*)mapped_resource.pData;
VERTEX_CONSTANT_BUFFER* pConstantBuffer = (VERTEX_CONSTANT_BUFFER*)mappedResource.pData; float L = 0.0f;
const float L = 0.0f; float R = ImGui::GetIO().DisplaySize.x;
const float R = ImGui::GetIO().DisplaySize.x; float B = ImGui::GetIO().DisplaySize.y;
const float B = ImGui::GetIO().DisplaySize.y; float T = 0.0f;
const float T = 0.0f; float mvp[4][4] =
const float mvp[4][4] =
{ {
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f }, { 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f }, { 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
{ 0.0f, 0.0f, 0.5f, 0.0f }, { 0.0f, 0.0f, 0.5f, 0.0f },
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f }, { (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
}; };
memcpy(&pConstantBuffer->mvp, mvp, sizeof(mvp)); memcpy(&constant_buffer->mvp, mvp, sizeof(mvp));
g_pd3dDeviceContext->Unmap(g_pVertexConstantBuffer, 0); ctx->Unmap(g_pVertexConstantBuffer, 0);
} }
// Setup viewport // Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!)
struct BACKUP_DX11_STATE
{ {
UINT ScissorRectsCount, ViewportsCount;
D3D11_RECT ScissorRects[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
D3D11_VIEWPORT Viewports[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
ID3D11RasterizerState* RS;
ID3D11BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
UINT StencilRef;
ID3D11DepthStencilState* DepthStencilState;
ID3D11ShaderResourceView* PSShaderResource;
ID3D11SamplerState* PSSampler;
ID3D11PixelShader* PS;
ID3D11VertexShader* VS;
UINT PSInstancesCount, VSInstancesCount;
ID3D11ClassInstance* PSInstances[256], *VSInstances[256]; // 256 is max according to PSSetShader documentation
D3D11_PRIMITIVE_TOPOLOGY PrimitiveTopology;
ID3D11Buffer* IndexBuffer, *VertexBuffer, *VSConstantBuffer;
UINT IndexBufferOffset, VertexBufferStride, VertexBufferOffset;
DXGI_FORMAT IndexBufferFormat;
ID3D11InputLayout* InputLayout;
};
BACKUP_DX11_STATE old;
old.ScissorRectsCount = old.ViewportsCount = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
old.PSInstancesCount = old.VSInstancesCount = 256;
ctx->PSGetShader(&old.PS, old.PSInstances, &old.PSInstancesCount);
ctx->VSGetShader(&old.VS, old.VSInstances, &old.VSInstancesCount);
ctx->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer);
ctx->IAGetPrimitiveTopology(&old.PrimitiveTopology);
ctx->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset);
ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
ctx->IAGetInputLayout(&old.InputLayout);
// Setup viewport
D3D11_VIEWPORT vp; D3D11_VIEWPORT vp;
memset(&vp, 0, sizeof(D3D11_VIEWPORT)); memset(&vp, 0, sizeof(D3D11_VIEWPORT));
vp.Width = ImGui::GetIO().DisplaySize.x; vp.Width = ImGui::GetIO().DisplaySize.x;
vp.Height = ImGui::GetIO().DisplaySize.y; vp.Height = ImGui::GetIO().DisplaySize.y;
vp.MinDepth = 0.0f; vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f; vp.MaxDepth = 1.0f;
vp.TopLeftX = 0; vp.TopLeftX = vp.TopLeftY = 0.0f;
vp.TopLeftY = 0; ctx->RSSetViewports(1, &vp);
g_pd3dDeviceContext->RSSetViewports(1, &vp);
}
// Bind shader and vertex buffers // Bind shader and vertex buffers
unsigned int stride = sizeof(ImDrawVert); unsigned int stride = sizeof(ImDrawVert);
unsigned int offset = 0; unsigned int offset = 0;
g_pd3dDeviceContext->IASetInputLayout(g_pInputLayout); ctx->IASetInputLayout(g_pInputLayout);
g_pd3dDeviceContext->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset); ctx->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset);
g_pd3dDeviceContext->IASetIndexBuffer(g_pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0); ctx->IASetIndexBuffer(g_pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
g_pd3dDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
g_pd3dDeviceContext->VSSetShader(g_pVertexShader, NULL, 0); ctx->VSSetShader(g_pVertexShader, NULL, 0);
g_pd3dDeviceContext->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer); ctx->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer);
g_pd3dDeviceContext->PSSetShader(g_pPixelShader, NULL, 0); ctx->PSSetShader(g_pPixelShader, NULL, 0);
g_pd3dDeviceContext->PSSetSamplers(0, 1, &g_pFontSampler); ctx->PSSetSamplers(0, 1, &g_pFontSampler);
// Setup render state // Setup render state
const float blendFactor[4] = { 0.f, 0.f, 0.f, 0.f }; const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
g_pd3dDeviceContext->OMSetBlendState(g_pBlendState, blendFactor, 0xffffffff); ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
g_pd3dDeviceContext->RSSetState(g_pRasterizerState); ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists // Render command lists
int vtx_offset = 0; int vtx_offset = 0;
@ -160,19 +204,32 @@ void ImGui_ImplDX11_RenderDrawLists(ImDrawData* draw_data)
else else
{ {
const D3D11_RECT r = { (LONG)pcmd->ClipRect.x, (LONG)pcmd->ClipRect.y, (LONG)pcmd->ClipRect.z, (LONG)pcmd->ClipRect.w }; const D3D11_RECT r = { (LONG)pcmd->ClipRect.x, (LONG)pcmd->ClipRect.y, (LONG)pcmd->ClipRect.z, (LONG)pcmd->ClipRect.w };
g_pd3dDeviceContext->PSSetShaderResources(0, 1, (ID3D11ShaderResourceView**)&pcmd->TextureId); ctx->PSSetShaderResources(0, 1, (ID3D11ShaderResourceView**)&pcmd->TextureId);
g_pd3dDeviceContext->RSSetScissorRects(1, &r); ctx->RSSetScissorRects(1, &r);
g_pd3dDeviceContext->DrawIndexed(pcmd->ElemCount, idx_offset, vtx_offset); ctx->DrawIndexed(pcmd->ElemCount, idx_offset, vtx_offset);
} }
idx_offset += pcmd->ElemCount; idx_offset += pcmd->ElemCount;
} }
vtx_offset += cmd_list->VtxBuffer.size(); vtx_offset += cmd_list->VtxBuffer.size();
} }
// Restore modified state // Restore modified DX state
g_pd3dDeviceContext->IASetInputLayout(NULL); ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
g_pd3dDeviceContext->PSSetShader(NULL, NULL, 0); ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
g_pd3dDeviceContext->VSSetShader(NULL, NULL, 0); ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
for (UINT i = 0; i < old.PSInstancesCount; i++) if (old.PSInstances[i]) old.PSInstances[i]->Release();
ctx->VSSetShader(old.VS, old.VSInstances, old.VSInstancesCount); if (old.VS) old.VS->Release();
ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release();
for (UINT i = 0; i < old.VSInstancesCount; i++) if (old.VSInstances[i]) old.VSInstances[i]->Release();
ctx->IASetPrimitiveTopology(old.PrimitiveTopology);
ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release();
ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release();
ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
} }
IMGUI_API LRESULT ImGui_ImplDX11_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) IMGUI_API LRESULT ImGui_ImplDX11_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam)
@ -232,31 +289,31 @@ static void ImGui_ImplDX11_CreateFontsTexture()
// Upload texture to graphics system // Upload texture to graphics system
{ {
D3D11_TEXTURE2D_DESC texDesc; D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&texDesc, sizeof(texDesc)); ZeroMemory(&desc, sizeof(desc));
texDesc.Width = width; desc.Width = width;
texDesc.Height = height; desc.Height = height;
texDesc.MipLevels = 1; desc.MipLevels = 1;
texDesc.ArraySize = 1; desc.ArraySize = 1;
texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
texDesc.SampleDesc.Count = 1; desc.SampleDesc.Count = 1;
texDesc.Usage = D3D11_USAGE_DEFAULT; desc.Usage = D3D11_USAGE_DEFAULT;
texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
texDesc.CPUAccessFlags = 0; desc.CPUAccessFlags = 0;
ID3D11Texture2D *pTexture = NULL; ID3D11Texture2D *pTexture = NULL;
D3D11_SUBRESOURCE_DATA subResource; D3D11_SUBRESOURCE_DATA subResource;
subResource.pSysMem = pixels; subResource.pSysMem = pixels;
subResource.SysMemPitch = texDesc.Width * 4; subResource.SysMemPitch = desc.Width * 4;
subResource.SysMemSlicePitch = 0; subResource.SysMemSlicePitch = 0;
g_pd3dDevice->CreateTexture2D(&texDesc, &subResource, &pTexture); g_pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
// Create texture view // Create texture view
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
ZeroMemory(&srvDesc, sizeof(srvDesc)); ZeroMemory(&srvDesc, sizeof(srvDesc));
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = texDesc.MipLevels; srvDesc.Texture2D.MipLevels = desc.MipLevels;
srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.MostDetailedMip = 0;
g_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &g_pFontTextureView); g_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &g_pFontTextureView);
pTexture->Release(); pTexture->Release();
@ -267,17 +324,17 @@ static void ImGui_ImplDX11_CreateFontsTexture()
// Create texture sampler // Create texture sampler
{ {
D3D11_SAMPLER_DESC samplerDesc; D3D11_SAMPLER_DESC desc;
ZeroMemory(&samplerDesc, sizeof(samplerDesc)); ZeroMemory(&desc, sizeof(desc));
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.MipLODBias = 0.f; desc.MipLODBias = 0.f;
samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
samplerDesc.MinLOD = 0.f; desc.MinLOD = 0.f;
samplerDesc.MaxLOD = 0.f; desc.MaxLOD = 0.f;
g_pd3dDevice->CreateSamplerState(&samplerDesc, &g_pFontSampler); g_pd3dDevice->CreateSamplerState(&desc, &g_pFontSampler);
} }
} }
@ -288,6 +345,12 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
if (g_pFontSampler) if (g_pFontSampler)
ImGui_ImplDX11_InvalidateDeviceObjects(); ImGui_ImplDX11_InvalidateDeviceObjects();
// By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
// If you would like to use this DX11 sample code but remove this dependency you can:
// 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution]
// 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
// See https://github.com/ocornut/imgui/pull/638 for sources and details.
// Create the vertex shader // Create the vertex shader
{ {
static const char* vertexShader = static const char* vertexShader =
@ -325,24 +388,23 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
return false; return false;
// Create the input layout // Create the input layout
D3D11_INPUT_ELEMENT_DESC localLayout[] = { D3D11_INPUT_ELEMENT_DESC local_layout[] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->pos), D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->pos), D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->uv), D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->uv), D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D11_INPUT_PER_VERTEX_DATA, 0 },
}; };
if (g_pd3dDevice->CreateInputLayout(local_layout, 3, g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK)
if (g_pd3dDevice->CreateInputLayout(localLayout, 3, g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK)
return false; return false;
// Create the constant buffer // Create the constant buffer
{ {
D3D11_BUFFER_DESC cbDesc; D3D11_BUFFER_DESC desc;
cbDesc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER); desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER);
cbDesc.Usage = D3D11_USAGE_DYNAMIC; desc.Usage = D3D11_USAGE_DYNAMIC;
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
cbDesc.MiscFlags = 0; desc.MiscFlags = 0;
g_pd3dDevice->CreateBuffer(&cbDesc, NULL, &g_pVertexConstantBuffer); g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pVertexConstantBuffer);
} }
} }
@ -398,6 +460,20 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState); g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
} }
// Create depth-stencil State
{
D3D11_DEPTH_STENCIL_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.DepthEnable = false;
desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
desc.DepthFunc = D3D11_COMPARISON_ALWAYS;
desc.StencilEnable = false;
desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
desc.BackFace = desc.FrontFace;
g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
}
ImGui_ImplDX11_CreateFontsTexture(); ImGui_ImplDX11_CreateFontsTexture();
return true; return true;
@ -414,6 +490,7 @@ void ImGui_ImplDX11_InvalidateDeviceObjects()
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; } if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; } if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; } if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; } if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; } if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
@ -472,7 +549,7 @@ void ImGui_ImplDX11_Shutdown()
void ImGui_ImplDX11_NewFrame() void ImGui_ImplDX11_NewFrame()
{ {
if (!g_pVB) if (!g_pFontSampler)
ImGui_ImplDX11_CreateDeviceObjects(); ImGui_ImplDX11_CreateDeviceObjects();
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
@ -492,6 +569,7 @@ void ImGui_ImplDX11_NewFrame()
io.KeyCtrl = (GetKeyState(VK_CONTROL) & 0x8000) != 0; io.KeyCtrl = (GetKeyState(VK_CONTROL) & 0x8000) != 0;
io.KeyShift = (GetKeyState(VK_SHIFT) & 0x8000) != 0; io.KeyShift = (GetKeyState(VK_SHIFT) & 0x8000) != 0;
io.KeyAlt = (GetKeyState(VK_MENU) & 0x8000) != 0; io.KeyAlt = (GetKeyState(VK_MENU) & 0x8000) != 0;
io.KeySuper = false;
// io.KeysDown : filled by WM_KEYDOWN/WM_KEYUP events // io.KeysDown : filled by WM_KEYDOWN/WM_KEYUP events
// io.MousePos : filled by WM_MOUSEMOVE events // io.MousePos : filled by WM_MOUSEMOVE events
// io.MouseDown : filled by WM_*BUTTON* events // io.MouseDown : filled by WM_*BUTTON* events

View File

@ -1,4 +1,6 @@
// ImGui Win32 + DirectX11 binding // ImGui Win32 + DirectX11 binding
// In this binding, ImTextureID is used to store a 'ID3D11ShaderResourceView*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.

View File

@ -4,7 +4,6 @@
#include <imgui.h> #include <imgui.h>
#include "imgui_impl_dx11.h" #include "imgui_impl_dx11.h"
#include <d3d11.h> #include <d3d11.h>
#include <d3dcompiler.h>
#define DIRECTINPUT_VERSION 0x0800 #define DIRECTINPUT_VERSION 0x0800
#include <dinput.h> #include <dinput.h>
#include <tchar.h> #include <tchar.h>
@ -65,27 +64,6 @@ HRESULT CreateDeviceD3D(HWND hWnd)
if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 1, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK) if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 1, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK)
return E_FAIL; return E_FAIL;
// Setup rasterizer
{
D3D11_RASTERIZER_DESC RSDesc;
memset(&RSDesc, 0, sizeof(D3D11_RASTERIZER_DESC));
RSDesc.FillMode = D3D11_FILL_SOLID;
RSDesc.CullMode = D3D11_CULL_NONE;
RSDesc.FrontCounterClockwise = FALSE;
RSDesc.DepthBias = 0;
RSDesc.SlopeScaledDepthBias = 0.0f;
RSDesc.DepthBiasClamp = 0;
RSDesc.DepthClipEnable = TRUE;
RSDesc.ScissorEnable = TRUE;
RSDesc.AntialiasedLineEnable = FALSE;
RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
ID3D11RasterizerState* pRState = NULL;
g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
g_pd3dDeviceContext->RSSetState(pRState);
pRState->Release();
}
CreateRenderTarget(); CreateRenderTarget();
return S_OK; return S_OK;

View File

@ -1,3 +1,3 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. @REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
mkdir Debug mkdir Debug
cl /nologo /Zi /MD /I ..\.. /I "%DXSDK_DIR%/Include" /D UNICODE /D _UNICODE *.cpp ..\..\*.cpp /FeDebug/directx9_example.exe /FoDebug/ /link /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d9.lib d3dx9d.lib cl /nologo /Zi /MD /I ..\.. /I "%DXSDK_DIR%/Include" /D UNICODE /D _UNICODE *.cpp ..\..\*.cpp /FeDebug/directx9_example.exe /FoDebug/ /link /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d9.lib

View File

@ -86,7 +86,7 @@
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(DXSDK_DIR)Lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>$(DXSDK_DIR)Lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>d3d9.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -99,7 +99,7 @@
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(DXSDK_DIR)Lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>$(DXSDK_DIR)Lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>d3d9.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -116,7 +116,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(DXSDK_DIR)Lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>$(DXSDK_DIR)Lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>d3d9.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -133,7 +133,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(DXSDK_DIR)Lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>$(DXSDK_DIR)Lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>d3d9.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>

View File

@ -1,4 +1,6 @@
// ImGui Win32 + DirectX9 binding // ImGui Win32 + DirectX9 binding
// In this binding, ImTextureID is used to store a 'LPDIRECT3DTEXTURE9' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@ -8,7 +10,7 @@
#include "imgui_impl_dx9.h" #include "imgui_impl_dx9.h"
// DirectX // DirectX
#include <d3dx9.h> #include <d3d9.h>
#define DIRECTINPUT_VERSION 0x0800 #define DIRECTINPUT_VERSION 0x0800
#include <dinput.h> #include <dinput.h>
@ -24,9 +26,9 @@ static int g_VertexBufferSize = 5000, g_IndexBufferSize = 1
struct CUSTOMVERTEX struct CUSTOMVERTEX
{ {
D3DXVECTOR3 pos; float pos[3];
D3DCOLOR col; D3DCOLOR col;
D3DXVECTOR2 uv; float uv[2];
}; };
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1) #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
@ -35,6 +37,11 @@ struct CUSTOMVERTEX
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
void ImGui_ImplDX9_RenderDrawLists(ImDrawData* draw_data) void ImGui_ImplDX9_RenderDrawLists(ImDrawData* draw_data)
{ {
// Avoid rendering when minimized
ImGuiIO& io = ImGui::GetIO();
if (io.DisplaySize.x <= 0.0f || io.DisplaySize.y <= 0.0f)
return;
// Create and grow buffers if needed // Create and grow buffers if needed
if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount) if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount)
{ {
@ -51,6 +58,11 @@ void ImGui_ImplDX9_RenderDrawLists(ImDrawData* draw_data)
return; return;
} }
// Backup the DX9 state
IDirect3DStateBlock9* d3d9_state_block = NULL;
if (g_pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0)
return;
// Copy and convert all vertices into a single contiguous buffer // Copy and convert all vertices into a single contiguous buffer
CUSTOMVERTEX* vtx_dst; CUSTOMVERTEX* vtx_dst;
ImDrawIdx* idx_dst; ImDrawIdx* idx_dst;
@ -64,12 +76,12 @@ void ImGui_ImplDX9_RenderDrawLists(ImDrawData* draw_data)
const ImDrawVert* vtx_src = &cmd_list->VtxBuffer[0]; const ImDrawVert* vtx_src = &cmd_list->VtxBuffer[0];
for (int i = 0; i < cmd_list->VtxBuffer.size(); i++) for (int i = 0; i < cmd_list->VtxBuffer.size(); i++)
{ {
vtx_dst->pos.x = vtx_src->pos.x; vtx_dst->pos[0] = vtx_src->pos.x;
vtx_dst->pos.y = vtx_src->pos.y; vtx_dst->pos[1] = vtx_src->pos.y;
vtx_dst->pos.z = 0.0f; vtx_dst->pos[2] = 0.0f;
vtx_dst->col = (vtx_src->col & 0xFF00FF00) | ((vtx_src->col & 0xFF0000)>>16) | ((vtx_src->col & 0xFF) << 16); // RGBA --> ARGB for DirectX9 vtx_dst->col = (vtx_src->col & 0xFF00FF00) | ((vtx_src->col & 0xFF0000)>>16) | ((vtx_src->col & 0xFF) << 16); // RGBA --> ARGB for DirectX9
vtx_dst->uv.x = vtx_src->uv.x; vtx_dst->uv[0] = vtx_src->uv.x;
vtx_dst->uv.y = vtx_src->uv.y; vtx_dst->uv[1] = vtx_src->uv.y;
vtx_dst++; vtx_dst++;
vtx_src++; vtx_src++;
} }
@ -78,37 +90,47 @@ void ImGui_ImplDX9_RenderDrawLists(ImDrawData* draw_data)
} }
g_pVB->Unlock(); g_pVB->Unlock();
g_pIB->Unlock(); g_pIB->Unlock();
g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) ); g_pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX));
g_pd3dDevice->SetIndices( g_pIB ); g_pd3dDevice->SetIndices(g_pIB);
g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX ); g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
// Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing // Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing
g_pd3dDevice->SetPixelShader( NULL ); g_pd3dDevice->SetPixelShader(NULL);
g_pd3dDevice->SetVertexShader( NULL ); g_pd3dDevice->SetVertexShader(NULL);
g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ); g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, false ); g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, false);
g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, false ); g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, false);
g_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, true ); g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
g_pd3dDevice->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD ); g_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, false);
g_pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, false ); g_pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
g_pd3dDevice->SetRenderState( D3DRS_SCISSORTESTENABLE, true ); g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, true);
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 ); g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE ); g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
// Setup orthographic projection matrix // Setup orthographic projection matrix
D3DXMATRIXA16 mat; // Being agnostic of whether <d3dx9.h> or <DirectXMath.h> can be used, we aren't relying on D3DXMatrixIdentity()/D3DXMatrixOrthoOffCenterLH() or DirectX::XMMatrixIdentity()/DirectX::XMMatrixOrthographicOffCenterLH()
D3DXMatrixIdentity(&mat); {
g_pd3dDevice->SetTransform( D3DTS_WORLD, &mat ); const float L = 0.5f, R = io.DisplaySize.x+0.5f, T = 0.5f, B = io.DisplaySize.y+0.5f;
g_pd3dDevice->SetTransform( D3DTS_VIEW, &mat ); D3DMATRIX mat_identity = { { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } };
D3DXMatrixOrthoOffCenterLH( &mat, 0.5f, ImGui::GetIO().DisplaySize.x+0.5f, ImGui::GetIO().DisplaySize.y+0.5f, 0.5f, -1.0f, +1.0f ); D3DMATRIX mat_projection =
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &mat ); {
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,
(L+R)/(L-R), (T+B)/(B-T), 0.5f, 1.0f,
};
g_pd3dDevice->SetTransform(D3DTS_WORLD, &mat_identity);
g_pd3dDevice->SetTransform(D3DTS_VIEW, &mat_identity);
g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat_projection);
}
// Render command lists // Render command lists
int vtx_offset = 0; int vtx_offset = 0;
@ -126,14 +148,18 @@ void ImGui_ImplDX9_RenderDrawLists(ImDrawData* draw_data)
else else
{ {
const RECT r = { (LONG)pcmd->ClipRect.x, (LONG)pcmd->ClipRect.y, (LONG)pcmd->ClipRect.z, (LONG)pcmd->ClipRect.w }; const RECT r = { (LONG)pcmd->ClipRect.x, (LONG)pcmd->ClipRect.y, (LONG)pcmd->ClipRect.z, (LONG)pcmd->ClipRect.w };
g_pd3dDevice->SetTexture( 0, (LPDIRECT3DTEXTURE9)pcmd->TextureId ); g_pd3dDevice->SetTexture(0, (LPDIRECT3DTEXTURE9)pcmd->TextureId);
g_pd3dDevice->SetScissorRect( &r ); g_pd3dDevice->SetScissorRect(&r);
g_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, vtx_offset, 0, (UINT)cmd_list->VtxBuffer.size(), idx_offset, pcmd->ElemCount/3 ); g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, vtx_offset, 0, (UINT)cmd_list->VtxBuffer.size(), idx_offset, pcmd->ElemCount/3);
} }
idx_offset += pcmd->ElemCount; idx_offset += pcmd->ElemCount;
} }
vtx_offset += cmd_list->VtxBuffer.size(); vtx_offset += cmd_list->VtxBuffer.size();
} }
// Restore the DX9 state
d3d9_state_block->Apply();
d3d9_state_block->Release();
} }
IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam)
@ -234,11 +260,11 @@ static bool ImGui_ImplDX9_CreateFontsTexture()
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
unsigned char* pixels; unsigned char* pixels;
int width, height, bytes_per_pixel; int width, height, bytes_per_pixel;
io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height, &bytes_per_pixel); io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height, &bytes_per_pixel);
// Upload texture to graphics system // Upload texture to graphics system
g_FontTexture = NULL; g_FontTexture = NULL;
if (D3DXCreateTexture(g_pd3dDevice, width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8, D3DPOOL_DEFAULT, &g_FontTexture) < 0) if (g_pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_FontTexture, NULL) < 0)
return false; return false;
D3DLOCKED_RECT tex_locked_rect; D3DLOCKED_RECT tex_locked_rect;
if (g_FontTexture->LockRect(0, &tex_locked_rect, NULL, 0) != D3D_OK) if (g_FontTexture->LockRect(0, &tex_locked_rect, NULL, 0) != D3D_OK)
@ -306,6 +332,7 @@ void ImGui_ImplDX9_NewFrame()
io.KeyCtrl = (GetKeyState(VK_CONTROL) & 0x8000) != 0; io.KeyCtrl = (GetKeyState(VK_CONTROL) & 0x8000) != 0;
io.KeyShift = (GetKeyState(VK_SHIFT) & 0x8000) != 0; io.KeyShift = (GetKeyState(VK_SHIFT) & 0x8000) != 0;
io.KeyAlt = (GetKeyState(VK_MENU) & 0x8000) != 0; io.KeyAlt = (GetKeyState(VK_MENU) & 0x8000) != 0;
io.KeySuper = false;
// io.KeysDown : filled by WM_KEYDOWN/WM_KEYUP events // io.KeysDown : filled by WM_KEYDOWN/WM_KEYUP events
// io.MousePos : filled by WM_MOUSEMOVE events // io.MousePos : filled by WM_MOUSEMOVE events
// io.MouseDown : filled by WM_*BUTTON* events // io.MouseDown : filled by WM_*BUTTON* events

View File

@ -1,4 +1,6 @@
// ImGui Win32 + DirectX9 binding // ImGui Win32 + DirectX9 binding
// In this binding, ImTextureID is used to store a 'LPDIRECT3DTEXTURE9' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.

View File

@ -3,7 +3,7 @@
#include <imgui.h> #include <imgui.h>
#include "imgui_impl_dx9.h" #include "imgui_impl_dx9.h"
#include <d3dx9.h> #include <d3d9.h>
#define DIRECTINPUT_VERSION 0x0800 #define DIRECTINPUT_VERSION 0x0800
#include <dinput.h> #include <dinput.h>
#include <tchar.h> #include <tchar.h>

View File

@ -1,22 +0,0 @@
//
// imgui_impl_ios.h
// imguiex
//
// Joel Davis (joeld42@gmail.com)
//
#pragma once
#include <Foundation/Foundation.h>
#include <UIKit/UIKit.h>
@interface ImGuiHelper : NSObject
- (id) initWithView: (UIView *)view;
- (void)connectServer: (NSString*)serverName;
- (void)render;
- (void)newFrame;
@end

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/************************************************************************* /*************************************************************************
* GLFW 3.1 - www.glfw.org * GLFW 3.2 - www.glfw.org
* A library for OpenGL, window and input * A library for OpenGL, window and input
*------------------------------------------------------------------------ *------------------------------------------------------------------------
* Copyright (c) 2002-2006 Marcus Geelnard * Copyright (c) 2002-2006 Marcus Geelnard
@ -38,20 +38,30 @@ extern "C" {
* Doxygen documentation * Doxygen documentation
*************************************************************************/ *************************************************************************/
/*! @file glfw3native.h
* @brief The header of the native access functions.
*
* This is the header file of the native access functions. See @ref native for
* more information.
*/
/*! @defgroup native Native access /*! @defgroup native Native access
* *
* **By using the native access functions you assert that you know what you're * **By using the native access functions you assert that you know what you're
* doing and how to fix problems caused by using them. If you don't, you * doing and how to fix problems caused by using them. If you don't, you
* shouldn't be using them.** * shouldn't be using them.**
* *
* Before the inclusion of @ref glfw3native.h, you must define exactly one * Before the inclusion of @ref glfw3native.h, you may define exactly one
* window system API macro and exactly one context creation API macro. Failure * window system API macro and zero or more context creation API macros.
* to do this will cause a compile-time error. *
* The chosen backends must match those the library was compiled for. Failure
* to do this will cause a link-time error.
* *
* The available window API macros are: * The available window API macros are:
* * `GLFW_EXPOSE_NATIVE_WIN32` * * `GLFW_EXPOSE_NATIVE_WIN32`
* * `GLFW_EXPOSE_NATIVE_COCOA` * * `GLFW_EXPOSE_NATIVE_COCOA`
* * `GLFW_EXPOSE_NATIVE_X11` * * `GLFW_EXPOSE_NATIVE_X11`
* * `GLFW_EXPOSE_NATIVE_WAYLAND`
* * `GLFW_EXPOSE_NATIVE_MIR`
* *
* The available context API macros are: * The available context API macros are:
* * `GLFW_EXPOSE_NATIVE_WGL` * * `GLFW_EXPOSE_NATIVE_WGL`
@ -86,20 +96,23 @@ extern "C" {
#elif defined(GLFW_EXPOSE_NATIVE_X11) #elif defined(GLFW_EXPOSE_NATIVE_X11)
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h> #include <X11/extensions/Xrandr.h>
#else #elif defined(GLFW_EXPOSE_NATIVE_WAYLAND)
#error "No window API selected" #include <wayland-client.h>
#elif defined(GLFW_EXPOSE_NATIVE_MIR)
#include <mir_toolkit/mir_client_library.h>
#endif #endif
#if defined(GLFW_EXPOSE_NATIVE_WGL) #if defined(GLFW_EXPOSE_NATIVE_WGL)
/* WGL is declared by windows.h */ /* WGL is declared by windows.h */
#elif defined(GLFW_EXPOSE_NATIVE_NSGL) #endif
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
/* NSGL is declared by Cocoa.h */ /* NSGL is declared by Cocoa.h */
#elif defined(GLFW_EXPOSE_NATIVE_GLX) #endif
#if defined(GLFW_EXPOSE_NATIVE_GLX)
#include <GL/glx.h> #include <GL/glx.h>
#elif defined(GLFW_EXPOSE_NATIVE_EGL) #endif
#if defined(GLFW_EXPOSE_NATIVE_EGL)
#include <EGL/egl.h> #include <EGL/egl.h>
#else
#error "No context API selected"
#endif #endif
@ -114,11 +127,10 @@ extern "C" {
* of the specified monitor, or `NULL` if an [error](@ref error_handling) * of the specified monitor, or `NULL` if an [error](@ref error_handling)
* occurred. * occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.1.
* Added in GLFW 3.1.
* *
* @ingroup native * @ingroup native
*/ */
@ -130,11 +142,10 @@ GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor);
* `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an * `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.1.
* Added in GLFW 3.1.
* *
* @ingroup native * @ingroup native
*/ */
@ -145,11 +156,10 @@ GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);
* @return The `HWND` of the specified window, or `NULL` if an * @return The `HWND` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
@ -162,11 +172,10 @@ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
* @return The `HGLRC` of the specified window, or `NULL` if an * @return The `HGLRC` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
@ -179,11 +188,10 @@ GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
* @return The `CGDirectDisplayID` of the specified monitor, or * @return The `CGDirectDisplayID` of the specified monitor, or
* `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred. * `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.1.
* Added in GLFW 3.1.
* *
* @ingroup native * @ingroup native
*/ */
@ -194,11 +202,10 @@ GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
* @return The `NSWindow` of the specified window, or `nil` if an * @return The `NSWindow` of the specified window, or `nil` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
@ -211,11 +218,10 @@ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
* @return The `NSOpenGLContext` of the specified window, or `nil` if an * @return The `NSOpenGLContext` of the specified window, or `nil` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
@ -228,11 +234,10 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
* @return The `Display` used by GLFW, or `NULL` if an * @return The `Display` used by GLFW, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
@ -243,11 +248,10 @@ GLFWAPI Display* glfwGetX11Display(void);
* @return The `RRCrtc` of the specified monitor, or `None` if an * @return The `RRCrtc` of the specified monitor, or `None` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.1.
* Added in GLFW 3.1.
* *
* @ingroup native * @ingroup native
*/ */
@ -258,11 +262,10 @@ GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
* @return The `RROutput` of the specified monitor, or `None` if an * @return The `RROutput` of the specified monitor, or `None` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.1.
* Added in GLFW 3.1.
* *
* @ingroup native * @ingroup native
*/ */
@ -273,11 +276,10 @@ GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
* @return The `Window` of the specified window, or `None` if an * @return The `Window` of the specified window, or `None` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
@ -290,15 +292,116 @@ GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
* @return The `GLXContext` of the specified window, or `NULL` if an * @return The `GLXContext` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window); GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
/*! @brief Returns the `GLXWindow` of the specified window.
*
* @return The `GLXWindow` of the specified window, or `None` if an
* [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
/*! @brief Returns the `struct wl_display*` used by GLFW.
*
* @return The `struct wl_display*` used by GLFW, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI struct wl_display* glfwGetWaylandDisplay(void);
/*! @brief Returns the `struct wl_output*` of the specified monitor.
*
* @return The `struct wl_output*` of the specified monitor, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
/*! @brief Returns the main `struct wl_surface*` of the specified window.
*
* @return The main `struct wl_surface*` of the specified window, or `NULL` if
* an [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_MIR)
/*! @brief Returns the `MirConnection*` used by GLFW.
*
* @return The `MirConnection*` used by GLFW, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI MirConnection* glfwGetMirDisplay(void);
/*! @brief Returns the Mir output ID of the specified monitor.
*
* @return The Mir output ID of the specified monitor, or zero if an
* [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI int glfwGetMirMonitor(GLFWmonitor* monitor);
/*! @brief Returns the `MirSurface*` of the specified window.
*
* @return The `MirSurface*` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI MirSurface* glfwGetMirWindow(GLFWwindow* window);
#endif #endif
#if defined(GLFW_EXPOSE_NATIVE_EGL) #if defined(GLFW_EXPOSE_NATIVE_EGL)
@ -307,11 +410,10 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
* @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an * @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
@ -322,11 +424,10 @@ GLFWAPI EGLDisplay glfwGetEGLDisplay(void);
* @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an * @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
@ -337,11 +438,10 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
* @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an * @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */

View File

@ -1,4 +1,6 @@
// ImGui Marmalade binding with IwGx // ImGui Marmalade binding with IwGx
// In this binding, ImTextureID is used to store a 'CIwTexture*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@ -151,6 +153,7 @@ int32 ImGui_Marmalade_KeyCallback(void* SystemData, void* userData)
io.KeyCtrl = s3eKeyboardGetState(s3eKeyLeftControl) == S3E_KEY_STATE_DOWN || s3eKeyboardGetState(s3eKeyRightControl) == S3E_KEY_STATE_DOWN; io.KeyCtrl = s3eKeyboardGetState(s3eKeyLeftControl) == S3E_KEY_STATE_DOWN || s3eKeyboardGetState(s3eKeyRightControl) == S3E_KEY_STATE_DOWN;
io.KeyShift = s3eKeyboardGetState(s3eKeyLeftShift) == S3E_KEY_STATE_DOWN || s3eKeyboardGetState(s3eKeyRightShift) == S3E_KEY_STATE_DOWN; io.KeyShift = s3eKeyboardGetState(s3eKeyLeftShift) == S3E_KEY_STATE_DOWN || s3eKeyboardGetState(s3eKeyRightShift) == S3E_KEY_STATE_DOWN;
io.KeyAlt = s3eKeyboardGetState(s3eKeyLeftAlt) == S3E_KEY_STATE_DOWN || s3eKeyboardGetState(s3eKeyRightAlt) == S3E_KEY_STATE_DOWN; io.KeyAlt = s3eKeyboardGetState(s3eKeyLeftAlt) == S3E_KEY_STATE_DOWN || s3eKeyboardGetState(s3eKeyRightAlt) == S3E_KEY_STATE_DOWN;
io.KeySuper = s3eKeyboardGetState(s3eKeyLeftWindows) == S3E_KEY_STATE_DOWN || s3eKeyboardGetState(s3eKeyRightWindows) == S3E_KEY_STATE_DOWN;
return 0; return 0;
} }

View File

@ -1,4 +1,6 @@
// ImGui Marmalade binding with IwGx // ImGui Marmalade binding with IwGx
// In this binding, ImTextureID is used to store a 'CIwTexture*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.

View File

@ -20,7 +20,7 @@ UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S), Linux) #LINUX ifeq ($(UNAME_S), Linux) #LINUX
ECHO_MESSAGE = "Linux" ECHO_MESSAGE = "Linux"
LIBS = `pkg-config --static --libs glfw3` LIBS = -lGL `pkg-config --static --libs glfw3`
CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3`
CXXFLAGS += -Wall -Wformat CXXFLAGS += -Wall -Wformat
@ -30,8 +30,7 @@ endif
ifeq ($(UNAME_S), Darwin) #APPLE ifeq ($(UNAME_S), Darwin) #APPLE
ECHO_MESSAGE = "Mac OS X" ECHO_MESSAGE = "Mac OS X"
LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo
LIBS += -L/usr/local/lib LIBS += -L/usr/local/lib -lglfw3
LIBS += -lglfw3
CXXFLAGS = -I../../ -I../libs/gl3w -I/usr/local/Cellar/glew/1.10.0/include -I/usr/local/include CXXFLAGS = -I../../ -I../libs/gl3w -I/usr/local/Cellar/glew/1.10.0/include -I/usr/local/include
CXXFLAGS += -Wall -Wformat CXXFLAGS += -Wall -Wformat

View File

@ -1,4 +1,6 @@
// ImGui GLFW binding with OpenGL3 + shaders // ImGui GLFW binding with OpenGL3 + shaders
// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@ -33,9 +35,18 @@ static unsigned int g_VboHandle = 0, g_VaoHandle = 0, g_ElementsHandle = 0;
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawData* draw_data) void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawData* draw_data)
{ {
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
ImGuiIO& io = ImGui::GetIO();
int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x);
int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y);
if (fb_width == 0 || fb_height == 0)
return;
draw_data->ScaleClipRects(io.DisplayFramebufferScale);
// Backup GL state // Backup GL state
GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
GLint last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, &last_active_texture);
GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer); GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer);
GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
@ -58,12 +69,6 @@ void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawData* draw_data)
glEnable(GL_SCISSOR_TEST); glEnable(GL_SCISSOR_TEST);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
// Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays)
ImGuiIO& io = ImGui::GetIO();
int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x);
int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y);
draw_data->ScaleClipRects(io.DisplayFramebufferScale);
// Setup viewport, orthographic projection matrix // Setup viewport, orthographic projection matrix
glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height);
const float ortho_projection[4][4] = const float ortho_projection[4][4] =
@ -107,10 +112,11 @@ void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawData* draw_data)
// Restore modified GL state // Restore modified GL state
glUseProgram(last_program); glUseProgram(last_program);
glActiveTexture(last_active_texture);
glBindTexture(GL_TEXTURE_2D, last_texture); glBindTexture(GL_TEXTURE_2D, last_texture);
glBindVertexArray(last_vertex_array);
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer);
glBindVertexArray(last_vertex_array);
glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha);
glBlendFunc(last_blend_src, last_blend_dst); glBlendFunc(last_blend_src, last_blend_dst);
if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND); if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND);
@ -153,6 +159,7 @@ void ImGui_ImplGlfwGL3_KeyCallback(GLFWwindow*, int key, int, int action, int mo
io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL];
io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT];
io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT];
io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER];
} }
void ImGui_ImplGlfwGL3_CharCallback(GLFWwindow*, unsigned int c) void ImGui_ImplGlfwGL3_CharCallback(GLFWwindow*, unsigned int c)
@ -353,7 +360,7 @@ void ImGui_ImplGlfwGL3_NewFrame()
glfwGetWindowSize(g_Window, &w, &h); glfwGetWindowSize(g_Window, &w, &h);
glfwGetFramebufferSize(g_Window, &display_w, &display_h); glfwGetFramebufferSize(g_Window, &display_w, &display_h);
io.DisplaySize = ImVec2((float)w, (float)h); io.DisplaySize = ImVec2((float)w, (float)h);
io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h); io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0);
// Setup time step // Setup time step
double current_time = glfwGetTime(); double current_time = glfwGetTime();

View File

@ -1,4 +1,6 @@
// ImGui GLFW binding with OpenGL3 + shaders // ImGui GLFW binding with OpenGL3 + shaders
// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.

View File

@ -19,7 +19,7 @@ UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S), Linux) #LINUX ifeq ($(UNAME_S), Linux) #LINUX
ECHO_MESSAGE = "Linux" ECHO_MESSAGE = "Linux"
LIBS = `pkg-config --static --libs glfw3` LIBS = -lGL `pkg-config --static --libs glfw3`
CXXFLAGS = -I../../ `pkg-config --cflags glfw3` CXXFLAGS = -I../../ `pkg-config --cflags glfw3`
CXXFLAGS += -Wall -Wformat CXXFLAGS += -Wall -Wformat
@ -29,8 +29,7 @@ endif
ifeq ($(UNAME_S), Darwin) #APPLE ifeq ($(UNAME_S), Darwin) #APPLE
ECHO_MESSAGE = "Mac OS X" ECHO_MESSAGE = "Mac OS X"
LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo
LIBS += -L/usr/local/lib LIBS += -L/usr/local/lib -lglfw3
LIBS += -lglfw3
CXXFLAGS = -I../../ -I/usr/local/include CXXFLAGS = -I../../ -I/usr/local/include
CXXFLAGS += -Wall -Wformat CXXFLAGS += -Wall -Wformat

View File

@ -1,4 +1,10 @@
// ImGui GLFW binding with OpenGL // ImGui GLFW binding with OpenGL
// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
// If your context is GL3/GL3 then prefer using the code in opengl3_example.
// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render().
// We cannot do that from GL2 code because the function doesn't exist.
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@ -28,6 +34,14 @@ static GLuint g_FontTexture = 0;
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data)
{ {
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
ImGuiIO& io = ImGui::GetIO();
int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x);
int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y);
if (fb_width == 0 || fb_height == 0)
return;
draw_data->ScaleClipRects(io.DisplayFramebufferScale);
// We are using the OpenGL fixed pipeline to make the example code simpler to read! // We are using the OpenGL fixed pipeline to make the example code simpler to read!
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers.
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
@ -44,12 +58,6 @@ void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data)
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
//glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context
// Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays)
ImGuiIO& io = ImGui::GetIO();
int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x);
int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y);
draw_data->ScaleClipRects(io.DisplayFramebufferScale);
// Setup viewport, orthographic projection matrix // Setup viewport, orthographic projection matrix
glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height);
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
@ -93,7 +101,7 @@ void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data)
glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_VERTEX_ARRAY);
glBindTexture(GL_TEXTURE_2D, last_texture); glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture);
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glPopMatrix(); glPopMatrix();
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
@ -135,6 +143,7 @@ void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods)
io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL];
io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT];
io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT];
io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER];
} }
void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c)
@ -242,7 +251,7 @@ void ImGui_ImplGlfw_NewFrame()
glfwGetWindowSize(g_Window, &w, &h); glfwGetWindowSize(g_Window, &w, &h);
glfwGetFramebufferSize(g_Window, &display_w, &display_h); glfwGetFramebufferSize(g_Window, &display_w, &display_h);
io.DisplaySize = ImVec2((float)w, (float)h); io.DisplaySize = ImVec2((float)w, (float)h);
io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h); io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0);
// Setup time step // Setup time step
double current_time = glfwGetTime(); double current_time = glfwGetTime();

View File

@ -1,4 +1,10 @@
// ImGui GLFW binding with OpenGL // ImGui GLFW binding with OpenGL
// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
// If your context is GL3/GL3 then prefer using the code in opengl3_example.
// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render().
// We cannot do that from GL2 code because the function doesn't exist.
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.

View File

@ -18,5 +18,5 @@ c++ `sdl2-config --cflags` -I ../.. -I ../libs/gl3w main.cpp imgui_impl_sdl_gl3.
``` ```
brew install sdl2 brew install sdl2
c++ `sdl2-config --cflags` -I ../.. -I ../libs/gl3w main.cpp imgui_impl_sdl_gl3.cpp ../../imgui*.cpp ../libs/gl3w/GL/gl3w.c `sdl2-config --libs` -framework OpenGl -o sdl2example c++ `sdl2-config --cflags` -I ../.. -I ../libs/gl3w main.cpp imgui_impl_sdl_gl3.cpp ../../imgui*.cpp ../libs/gl3w/GL/gl3w.c `sdl2-config --libs` -framework OpenGl -framework CoreFoundation -o sdl2example
``` ```

View File

@ -1,4 +1,6 @@
// ImGui SDL2 binding with OpenGL3 // ImGui SDL2 binding with OpenGL3
// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@ -13,7 +15,6 @@
#include <GL/gl3w.h> #include <GL/gl3w.h>
// Data // Data
static SDL_Window* g_Window = NULL;
static double g_Time = 0.0f; static double g_Time = 0.0f;
static bool g_MousePressed[3] = { false, false, false }; static bool g_MousePressed[3] = { false, false, false };
static float g_MouseWheel = 0.0f; static float g_MouseWheel = 0.0f;
@ -28,9 +29,18 @@ static unsigned int g_VboHandle = 0, g_VaoHandle = 0, g_ElementsHandle = 0;
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data) void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data)
{ {
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
ImGuiIO& io = ImGui::GetIO();
int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x);
int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y);
if (fb_width == 0 || fb_height == 0)
return;
draw_data->ScaleClipRects(io.DisplayFramebufferScale);
// Backup GL state // Backup GL state
GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
GLint last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, &last_active_texture);
GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer); GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer);
GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
@ -53,12 +63,6 @@ void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data)
glEnable(GL_SCISSOR_TEST); glEnable(GL_SCISSOR_TEST);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
// Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays)
ImGuiIO& io = ImGui::GetIO();
int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x);
int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y);
draw_data->ScaleClipRects(io.DisplayFramebufferScale);
// Setup orthographic projection matrix // Setup orthographic projection matrix
glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height);
const float ortho_projection[4][4] = const float ortho_projection[4][4] =
@ -102,10 +106,11 @@ void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data)
// Restore modified GL state // Restore modified GL state
glUseProgram(last_program); glUseProgram(last_program);
glActiveTexture(last_active_texture);
glBindTexture(GL_TEXTURE_2D, last_texture); glBindTexture(GL_TEXTURE_2D, last_texture);
glBindVertexArray(last_vertex_array);
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer);
glBindVertexArray(last_vertex_array);
glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha);
glBlendFunc(last_blend_src, last_blend_dst); glBlendFunc(last_blend_src, last_blend_dst);
if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND); if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND);
@ -159,6 +164,7 @@ bool ImGui_ImplSdlGL3_ProcessEvent(SDL_Event* event)
io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0);
io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0);
io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0);
io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0);
return true; return true;
} }
} }
@ -292,10 +298,8 @@ void ImGui_ImplSdlGL3_InvalidateDeviceObjects()
} }
} }
bool ImGui_ImplSdlGL3_Init(SDL_Window *window) bool ImGui_ImplSdlGL3_Init(SDL_Window* window)
{ {
g_Window = window;
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.KeyMap[ImGuiKey_Tab] = SDLK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. io.KeyMap[ImGuiKey_Tab] = SDLK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT; io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT;
@ -326,6 +330,8 @@ bool ImGui_ImplSdlGL3_Init(SDL_Window *window)
SDL_VERSION(&wmInfo.version); SDL_VERSION(&wmInfo.version);
SDL_GetWindowWMInfo(window, &wmInfo); SDL_GetWindowWMInfo(window, &wmInfo);
io.ImeWindowHandle = wmInfo.info.win.window; io.ImeWindowHandle = wmInfo.info.win.window;
#else
(void)window;
#endif #endif
return true; return true;
@ -337,7 +343,7 @@ void ImGui_ImplSdlGL3_Shutdown()
ImGui::Shutdown(); ImGui::Shutdown();
} }
void ImGui_ImplSdlGL3_NewFrame() void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window)
{ {
if (!g_FontTexture) if (!g_FontTexture)
ImGui_ImplSdlGL3_CreateDeviceObjects(); ImGui_ImplSdlGL3_CreateDeviceObjects();
@ -346,9 +352,11 @@ void ImGui_ImplSdlGL3_NewFrame()
// Setup display size (every frame to accommodate for window resizing) // Setup display size (every frame to accommodate for window resizing)
int w, h; int w, h;
SDL_GetWindowSize(g_Window, &w, &h); int display_w, display_h;
SDL_GetWindowSize(window, &w, &h);
SDL_GL_GetDrawableSize(window, &display_w, &display_h);
io.DisplaySize = ImVec2((float)w, (float)h); io.DisplaySize = ImVec2((float)w, (float)h);
io.DisplayFramebufferScale = ImVec2(1.0f, 1.0f); io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0);
// Setup time step // Setup time step
Uint32 time = SDL_GetTicks(); Uint32 time = SDL_GetTicks();
@ -360,7 +368,7 @@ void ImGui_ImplSdlGL3_NewFrame()
// (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent())
int mx, my; int mx, my;
Uint32 mouseMask = SDL_GetMouseState(&mx, &my); Uint32 mouseMask = SDL_GetMouseState(&mx, &my);
if (SDL_GetWindowFlags(g_Window) & SDL_WINDOW_MOUSE_FOCUS) if (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS)
io.MousePos = ImVec2((float)mx, (float)my); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) io.MousePos = ImVec2((float)mx, (float)my); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
else else
io.MousePos = ImVec2(-1, -1); io.MousePos = ImVec2(-1, -1);

View File

@ -1,4 +1,6 @@
// ImGui SDL2 binding with OpenGL3 // ImGui SDL2 binding with OpenGL3
// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@ -7,9 +9,9 @@
struct SDL_Window; struct SDL_Window;
typedef union SDL_Event SDL_Event; typedef union SDL_Event SDL_Event;
IMGUI_API bool ImGui_ImplSdlGL3_Init(SDL_Window *window); IMGUI_API bool ImGui_ImplSdlGL3_Init(SDL_Window* window);
IMGUI_API void ImGui_ImplSdlGL3_Shutdown(); IMGUI_API void ImGui_ImplSdlGL3_Shutdown();
IMGUI_API void ImGui_ImplSdlGL3_NewFrame(); IMGUI_API void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window);
IMGUI_API bool ImGui_ImplSdlGL3_ProcessEvent(SDL_Event* event); IMGUI_API bool ImGui_ImplSdlGL3_ProcessEvent(SDL_Event* event);
// Use if you want to reset your rendering device without losing ImGui state. // Use if you want to reset your rendering device without losing ImGui state.

View File

@ -10,17 +10,19 @@
int main(int, char**) int main(int, char**)
{ {
// Setup SDL // Setup SDL
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0)
{ {
printf("Error: %s\n", SDL_GetError()); printf("Error: %s\n", SDL_GetError());
return -1; return -1;
} }
// Setup window // Setup window
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_DisplayMode current; SDL_DisplayMode current;
SDL_GetCurrentDisplayMode(0, &current); SDL_GetCurrentDisplayMode(0, &current);
@ -56,7 +58,7 @@ int main(int, char**)
if (event.type == SDL_QUIT) if (event.type == SDL_QUIT)
done = true; done = true;
} }
ImGui_ImplSdlGL3_NewFrame(); ImGui_ImplSdlGL3_NewFrame(window);
// 1. Show a simple window // 1. Show a simple window
// Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug"

View File

@ -1,4 +1,6 @@
// ImGui SDL2 binding with OpenGL // ImGui SDL2 binding with OpenGL
// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@ -21,6 +23,14 @@ static GLuint g_FontTexture = 0;
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
void ImGui_ImplSdl_RenderDrawLists(ImDrawData* draw_data) void ImGui_ImplSdl_RenderDrawLists(ImDrawData* draw_data)
{ {
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
ImGuiIO& io = ImGui::GetIO();
int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x);
int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y);
if (fb_width == 0 || fb_height == 0)
return;
draw_data->ScaleClipRects(io.DisplayFramebufferScale);
// We are using the OpenGL fixed pipeline to make the example code simpler to read! // We are using the OpenGL fixed pipeline to make the example code simpler to read!
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers.
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
@ -37,12 +47,6 @@ void ImGui_ImplSdl_RenderDrawLists(ImDrawData* draw_data)
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
//glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context
// Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays)
ImGuiIO& io = ImGui::GetIO();
int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x);
int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y);
draw_data->ScaleClipRects(io.DisplayFramebufferScale);
// Setup viewport, orthographic projection matrix // Setup viewport, orthographic projection matrix
glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height);
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
@ -86,7 +90,7 @@ void ImGui_ImplSdl_RenderDrawLists(ImDrawData* draw_data)
glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_VERTEX_ARRAY);
glBindTexture(GL_TEXTURE_2D, last_texture); glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture);
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glPopMatrix(); glPopMatrix();
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
@ -139,6 +143,7 @@ bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event)
io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0);
io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0);
io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0);
io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0);
return true; return true;
} }
} }
@ -181,7 +186,7 @@ void ImGui_ImplSdl_InvalidateDeviceObjects()
} }
} }
bool ImGui_ImplSdl_Init(SDL_Window *window) bool ImGui_ImplSdl_Init(SDL_Window* window)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.KeyMap[ImGuiKey_Tab] = SDLK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. io.KeyMap[ImGuiKey_Tab] = SDLK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
@ -213,6 +218,8 @@ bool ImGui_ImplSdl_Init(SDL_Window *window)
SDL_VERSION(&wmInfo.version); SDL_VERSION(&wmInfo.version);
SDL_GetWindowWMInfo(window, &wmInfo); SDL_GetWindowWMInfo(window, &wmInfo);
io.ImeWindowHandle = wmInfo.info.win.window; io.ImeWindowHandle = wmInfo.info.win.window;
#else
(void)window;
#endif #endif
return true; return true;
@ -233,8 +240,11 @@ void ImGui_ImplSdl_NewFrame(SDL_Window *window)
// Setup display size (every frame to accommodate for window resizing) // Setup display size (every frame to accommodate for window resizing)
int w, h; int w, h;
int display_w, display_h;
SDL_GetWindowSize(window, &w, &h); SDL_GetWindowSize(window, &w, &h);
SDL_GL_GetDrawableSize(window, &display_w, &display_h);
io.DisplaySize = ImVec2((float)w, (float)h); io.DisplaySize = ImVec2((float)w, (float)h);
io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0);
// Setup time step // Setup time step
Uint32 time = SDL_GetTicks(); Uint32 time = SDL_GetTicks();

View File

@ -1,4 +1,6 @@
// ImGui SDL2 binding with OpenGL // ImGui SDL2 binding with OpenGL
// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@ -7,9 +9,9 @@
struct SDL_Window; struct SDL_Window;
typedef union SDL_Event SDL_Event; typedef union SDL_Event SDL_Event;
IMGUI_API bool ImGui_ImplSdl_Init(SDL_Window *window); IMGUI_API bool ImGui_ImplSdl_Init(SDL_Window* window);
IMGUI_API void ImGui_ImplSdl_Shutdown(); IMGUI_API void ImGui_ImplSdl_Shutdown();
IMGUI_API void ImGui_ImplSdl_NewFrame(SDL_Window *window); IMGUI_API void ImGui_ImplSdl_NewFrame(SDL_Window* window);
IMGUI_API bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event); IMGUI_API bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event);
// Use if you want to reset your rendering device without losing ImGui state. // Use if you want to reset your rendering device without losing ImGui state.

View File

@ -10,7 +10,7 @@
int main(int, char**) int main(int, char**)
{ {
// Setup SDL // Setup SDL
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0)
{ {
printf("Error: %s\n", SDL_GetError()); printf("Error: %s\n", SDL_GetError());
return -1; return -1;

View File

@ -0,0 +1,36 @@
cmake_minimum_required(VERSION 2.8)
project(ImGuiGLFWVulkanExample C CXX)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug CACHE STRING "" FORCE)
endif()
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DVK_PROTOTYPES")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVK_PROTOTYPES")
# GLFW
set(GLFW_DIR ../../../glfw) # Set this to point to a up-to-date GLFW repo
option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" OFF)
option(GLFW_BUILD_TESTS "Build the GLFW test programs" OFF)
option(GLFW_BUILD_DOCS "Build the GLFW documentation" OFF)
option(GLFW_INSTALL "Generate installation target" OFF)
option(GLFW_DOCUMENT_INTERNALS "Include internals in documentation" OFF)
add_subdirectory(${GLFW_DIR} binary_dir EXCLUDE_FROM_ALL)
include_directories(${GLFW_DIR}/include)
# ImGui
set(IMGUI_DIR ../../)
include_directories(${IMGUI_DIR})
# Libraries
find_library(VULKAN_LIBRARY
NAMES vulkan vulkan-1)
set(LIBRARIES "glfw;${VULKAN_LIBRARY}")
# Use vulkan headers from glfw:
include_directories(${GLFW_DIR}/deps)
file(GLOB sources *.cpp)
add_executable(vulkan_example ${sources} ${IMGUI_DIR}/imgui.cpp ${IMGUI_DIR}/imgui_draw.cpp ${IMGUI_DIR}/imgui_demo.cpp)
target_link_libraries(vulkan_example ${LIBRARIES})

View File

@ -0,0 +1,4 @@
@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 ..\libs\glfw\include /I %VULKAN_SDK%\include *.cpp ..\..\*.cpp /FeDebug/vulkan_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 /libpath:%VULKAN_SDK%\bin32 glfw3.lib opengl32.lib gdi32.lib shell32.lib vulkan-1.lib

View File

@ -0,0 +1,4 @@
#!/bin/bash
glslangValidator -V -o glsl_shader.frag.spv glsl_shader.frag
glslangValidator -V -o glsl_shader.vert.spv glsl_shader.vert
spirv-remap --map all --dce all --strip-all --input glsl_shader.frag.spv glsl_shader.vert.spv --output ./

View File

@ -0,0 +1,14 @@
#version 450 core
layout(location = 0, index = 0) out vec4 fColor;
layout(set=0, binding=0) uniform sampler2D sTexture;
in block{
vec4 Color;
vec2 UV;
} In;
void main()
{
fColor = In.Color * texture(sTexture, In.UV.st);
}

View File

@ -0,0 +1,21 @@
#version 450 core
layout(location = 0) in vec2 aPos;
layout(location = 1) in vec2 aUV;
layout(location = 2) in vec4 aColor;
layout(push_constant) uniform uPushConstant{
vec2 uScale;
vec2 uTranslate;
} pc;
out block{
vec4 Color;
vec2 UV;
} Out;
void main()
{
Out.Color = aColor;
Out.UV = aUV;
gl_Position = vec4(aPos*pc.uScale+pc.uTranslate, 0, 1);
}

View File

@ -0,0 +1,935 @@
// ImGui GLFW binding with Vulkan + shaders
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 5 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXX_CreateFontsTexture(), ImGui_ImplXXXX_NewFrame(), ImGui_ImplXXXX_Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
// https://github.com/ocornut/imgui
#include <imgui.h>
// GLFW
#define GLFW_INCLUDE_NONE
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
#ifdef _WIN32
#undef APIENTRY
#define GLFW_EXPOSE_NATIVE_WIN32
#define GLFW_EXPOSE_NATIVE_WGL
#include <GLFW/glfw3native.h>
#endif
#include "imgui_impl_glfw_vulkan.h"
// GLFW Data
static GLFWwindow* g_Window = NULL;
static double g_Time = 0.0f;
static bool g_MousePressed[3] = { false, false, false };
static float g_MouseWheel = 0.0f;
// Vulkan Data
static VkAllocationCallbacks* g_Allocator = NULL;
static VkPhysicalDevice g_Gpu = VK_NULL_HANDLE;
static VkDevice g_Device = VK_NULL_HANDLE;
static VkRenderPass g_RenderPass = VK_NULL_HANDLE;
static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE;
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
static void (*g_CheckVkResult)(VkResult err) = NULL;
static VkCommandBuffer g_CommandBuffer = VK_NULL_HANDLE;
static size_t g_BufferMemoryAlignment = 256;
static VkPipelineCreateFlags g_PipelineCreateFlags = 0;
static int g_FrameIndex = 0;
static VkDescriptorSetLayout g_DescriptorSetLayout = VK_NULL_HANDLE;
static VkPipelineLayout g_PipelineLayout = VK_NULL_HANDLE;
static VkDescriptorSet g_DescriptorSet = VK_NULL_HANDLE;
static VkPipeline g_Pipeline = VK_NULL_HANDLE;
static VkSampler g_FontSampler = VK_NULL_HANDLE;
static VkDeviceMemory g_FontMemory = VK_NULL_HANDLE;
static VkImage g_FontImage = VK_NULL_HANDLE;
static VkImageView g_FontView = VK_NULL_HANDLE;
static VkDeviceMemory g_VertexBufferMemory[IMGUI_VK_QUEUED_FRAMES] = {};
static VkDeviceMemory g_IndexBufferMemory[IMGUI_VK_QUEUED_FRAMES] = {};
static size_t g_VertexBufferSize[IMGUI_VK_QUEUED_FRAMES] = {};
static size_t g_IndexBufferSize[IMGUI_VK_QUEUED_FRAMES] = {};
static VkBuffer g_VertexBuffer[IMGUI_VK_QUEUED_FRAMES] = {};
static VkBuffer g_IndexBuffer[IMGUI_VK_QUEUED_FRAMES] = {};
static VkDeviceMemory g_UploadBufferMemory = VK_NULL_HANDLE;
static VkBuffer g_UploadBuffer = VK_NULL_HANDLE;
static unsigned char __glsl_shader_vert_spv[] =
{
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00,
0x6c, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00,
0x11, 0x00, 0x02, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00,
0x01, 0x00, 0x00, 0x00, 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64,
0x2e, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0a, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1f, 0x16, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e,
0x00, 0x00, 0x00, 0x00, 0x47, 0x11, 0x00, 0x00, 0x41, 0x14, 0x00, 0x00,
0x6a, 0x16, 0x00, 0x00, 0x42, 0x13, 0x00, 0x00, 0x80, 0x14, 0x00, 0x00,
0x47, 0x00, 0x03, 0x00, 0x1a, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x47, 0x00, 0x04, 0x00, 0x41, 0x14, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x6a, 0x16, 0x00, 0x00,
0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
0xb1, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0xb1, 0x02, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x48, 0x00, 0x05, 0x00, 0xb1, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
0xb1, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0xb1, 0x02, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x80, 0x14, 0x00, 0x00,
0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
0x06, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x06, 0x04, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x47, 0x00, 0x03, 0x00, 0x06, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x47, 0x00, 0x04, 0x00, 0xfa, 0x16, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00,
0x21, 0x00, 0x03, 0x00, 0x02, 0x05, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x16, 0x00, 0x03, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x17, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00,
0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x04, 0x00,
0x1a, 0x04, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x97, 0x06, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x1a, 0x04, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x97, 0x06, 0x00, 0x00,
0x47, 0x11, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00,
0x0c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x2b, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0b, 0x0a, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x9a, 0x02, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
0x9a, 0x02, 0x00, 0x00, 0x41, 0x14, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x9b, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x1d, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00,
0x0e, 0x0a, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x90, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
0x3b, 0x00, 0x04, 0x00, 0x90, 0x02, 0x00, 0x00, 0x6a, 0x16, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x91, 0x02, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00,
0x0b, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x2b, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0d, 0x0a, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x7f, 0x02, 0x00, 0x00,
0x0d, 0x00, 0x00, 0x00, 0x0d, 0x0a, 0x00, 0x00, 0x1e, 0x00, 0x06, 0x00,
0xb1, 0x02, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
0x7f, 0x02, 0x00, 0x00, 0x7f, 0x02, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x2e, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xb1, 0x02, 0x00, 0x00,
0x3b, 0x00, 0x04, 0x00, 0x2e, 0x05, 0x00, 0x00, 0x42, 0x13, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x90, 0x02, 0x00, 0x00,
0x80, 0x14, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x04, 0x00,
0x06, 0x04, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x83, 0x06, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
0x06, 0x04, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x83, 0x06, 0x00, 0x00,
0xfa, 0x16, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x92, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
0x2b, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0c, 0x0a, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00,
0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x36, 0x00, 0x05, 0x00,
0x08, 0x00, 0x00, 0x00, 0x1f, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x05, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x6b, 0x60, 0x00, 0x00,
0x3d, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x71, 0x4e, 0x00, 0x00,
0x41, 0x14, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x9b, 0x02, 0x00, 0x00,
0xaa, 0x26, 0x00, 0x00, 0x47, 0x11, 0x00, 0x00, 0x0b, 0x0a, 0x00, 0x00,
0x3e, 0x00, 0x03, 0x00, 0xaa, 0x26, 0x00, 0x00, 0x71, 0x4e, 0x00, 0x00,
0x3d, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00, 0xda, 0x35, 0x00, 0x00,
0x6a, 0x16, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x91, 0x02, 0x00, 0x00,
0xea, 0x50, 0x00, 0x00, 0x47, 0x11, 0x00, 0x00, 0x0e, 0x0a, 0x00, 0x00,
0x3e, 0x00, 0x03, 0x00, 0xea, 0x50, 0x00, 0x00, 0xda, 0x35, 0x00, 0x00,
0x3d, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00, 0xc7, 0x35, 0x00, 0x00,
0x80, 0x14, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x92, 0x02, 0x00, 0x00,
0xef, 0x56, 0x00, 0x00, 0xfa, 0x16, 0x00, 0x00, 0x0b, 0x0a, 0x00, 0x00,
0x3d, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00, 0xe0, 0x29, 0x00, 0x00,
0xef, 0x56, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x13, 0x00, 0x00, 0x00,
0xa0, 0x22, 0x00, 0x00, 0xc7, 0x35, 0x00, 0x00, 0xe0, 0x29, 0x00, 0x00,
0x41, 0x00, 0x05, 0x00, 0x92, 0x02, 0x00, 0x00, 0x42, 0x2c, 0x00, 0x00,
0xfa, 0x16, 0x00, 0x00, 0x0e, 0x0a, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
0x13, 0x00, 0x00, 0x00, 0x09, 0x60, 0x00, 0x00, 0x42, 0x2c, 0x00, 0x00,
0x81, 0x00, 0x05, 0x00, 0x13, 0x00, 0x00, 0x00, 0xd1, 0x4e, 0x00, 0x00,
0xa0, 0x22, 0x00, 0x00, 0x09, 0x60, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00,
0x0d, 0x00, 0x00, 0x00, 0xa1, 0x41, 0x00, 0x00, 0xd1, 0x4e, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00,
0x84, 0x36, 0x00, 0x00, 0xd1, 0x4e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x50, 0x00, 0x07, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x54, 0x47, 0x00, 0x00,
0xa1, 0x41, 0x00, 0x00, 0x84, 0x36, 0x00, 0x00, 0x0c, 0x0a, 0x00, 0x00,
0x8a, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x9b, 0x02, 0x00, 0x00,
0x17, 0x2f, 0x00, 0x00, 0x42, 0x13, 0x00, 0x00, 0x0b, 0x0a, 0x00, 0x00,
0x3e, 0x00, 0x03, 0x00, 0x17, 0x2f, 0x00, 0x00, 0x54, 0x47, 0x00, 0x00,
0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00
};
static unsigned int __glsl_shader_vert_spv_len = 1172;
static unsigned char __glsl_shader_frag_spv[] =
{
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00,
0x6c, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00,
0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30,
0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00,
0x1f, 0x16, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00,
0x7a, 0x0c, 0x00, 0x00, 0x35, 0x16, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00,
0x1f, 0x16, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
0x7a, 0x0c, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x47, 0x00, 0x04, 0x00, 0x7a, 0x0c, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x1a, 0x04, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0xec, 0x14, 0x00, 0x00,
0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
0xec, 0x14, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x13, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00,
0x02, 0x05, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00,
0x0d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00,
0x1d, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x9a, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x1d, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x9a, 0x02, 0x00, 0x00,
0x7a, 0x0c, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00,
0x13, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x1e, 0x00, 0x04, 0x00, 0x1a, 0x04, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
0x13, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x97, 0x06, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x1a, 0x04, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
0x97, 0x06, 0x00, 0x00, 0x35, 0x16, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x15, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00,
0x0b, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x9b, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
0x19, 0x00, 0x09, 0x00, 0x96, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1b, 0x00, 0x03, 0x00, 0xfe, 0x01, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x7b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xfe, 0x01, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x7b, 0x04, 0x00, 0x00,
0xec, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
0x0c, 0x00, 0x00, 0x00, 0x0e, 0x0a, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x90, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x13, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x08, 0x00, 0x00, 0x00,
0x1f, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00,
0xf8, 0x00, 0x02, 0x00, 0x6b, 0x5d, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
0x9b, 0x02, 0x00, 0x00, 0x8d, 0x1b, 0x00, 0x00, 0x35, 0x16, 0x00, 0x00,
0x0b, 0x0a, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00,
0x0b, 0x40, 0x00, 0x00, 0x8d, 0x1b, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
0xfe, 0x01, 0x00, 0x00, 0xc0, 0x36, 0x00, 0x00, 0xec, 0x14, 0x00, 0x00,
0x41, 0x00, 0x05, 0x00, 0x90, 0x02, 0x00, 0x00, 0xc2, 0x43, 0x00, 0x00,
0x35, 0x16, 0x00, 0x00, 0x0e, 0x0a, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
0x13, 0x00, 0x00, 0x00, 0x02, 0x4e, 0x00, 0x00, 0xc2, 0x43, 0x00, 0x00,
0x57, 0x00, 0x05, 0x00, 0x1d, 0x00, 0x00, 0x00, 0xb9, 0x46, 0x00, 0x00,
0xc0, 0x36, 0x00, 0x00, 0x02, 0x4e, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00,
0x1d, 0x00, 0x00, 0x00, 0xe4, 0x23, 0x00, 0x00, 0x0b, 0x40, 0x00, 0x00,
0xb9, 0x46, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x7a, 0x0c, 0x00, 0x00,
0xe4, 0x23, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00
};
static unsigned int __glsl_shader_frag_spv_len = 660;
static uint32_t ImGui_ImplGlfwVulkan_MemoryType(VkMemoryPropertyFlags properties, uint32_t type_bits)
{
VkPhysicalDeviceMemoryProperties prop;
vkGetPhysicalDeviceMemoryProperties(g_Gpu, &prop);
for (uint32_t i = 0; i < prop.memoryTypeCount; i++)
if ((prop.memoryTypes[i].propertyFlags & properties) == properties && type_bits & (1<<i))
return i;
return 0xffffffff; // Unable to find memoryType
}
static void ImGui_ImplGlfwVulkan_VkResult(VkResult err)
{
if (g_CheckVkResult)
g_CheckVkResult(err);
}
// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure)
void ImGui_ImplGlfwVulkan_RenderDrawLists(ImDrawData* draw_data)
{
VkResult err;
ImGuiIO& io = ImGui::GetIO();
// Create the Vertex Buffer:
size_t vertex_size = draw_data->TotalVtxCount * sizeof(ImDrawVert);
if (!g_VertexBuffer[g_FrameIndex] || g_VertexBufferSize[g_FrameIndex] < vertex_size)
{
if (g_VertexBuffer[g_FrameIndex])
vkDestroyBuffer(g_Device, g_VertexBuffer[g_FrameIndex], g_Allocator);
if (g_VertexBufferMemory[g_FrameIndex])
vkFreeMemory(g_Device, g_VertexBufferMemory[g_FrameIndex], g_Allocator);
size_t vertex_buffer_size = ((vertex_size-1) / g_BufferMemoryAlignment+1) * g_BufferMemoryAlignment;
VkBufferCreateInfo buffer_info = {};
buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
buffer_info.size = vertex_buffer_size;
buffer_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
err = vkCreateBuffer(g_Device, &buffer_info, g_Allocator, &g_VertexBuffer[g_FrameIndex]);
ImGui_ImplGlfwVulkan_VkResult(err);
VkMemoryRequirements req;
vkGetBufferMemoryRequirements(g_Device, g_VertexBuffer[g_FrameIndex], &req);
g_BufferMemoryAlignment = (g_BufferMemoryAlignment > req.alignment) ? g_BufferMemoryAlignment : req.alignment;
VkMemoryAllocateInfo alloc_info = {};
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
alloc_info.allocationSize = req.size;
alloc_info.memoryTypeIndex = ImGui_ImplGlfwVulkan_MemoryType(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, req.memoryTypeBits);
err = vkAllocateMemory(g_Device, &alloc_info, g_Allocator, &g_VertexBufferMemory[g_FrameIndex]);
ImGui_ImplGlfwVulkan_VkResult(err);
err = vkBindBufferMemory(g_Device, g_VertexBuffer[g_FrameIndex], g_VertexBufferMemory[g_FrameIndex], 0);
ImGui_ImplGlfwVulkan_VkResult(err);
g_VertexBufferSize[g_FrameIndex] = vertex_buffer_size;
}
// Create the Index Buffer:
size_t index_size = draw_data->TotalIdxCount * sizeof(ImDrawIdx);
if (!g_IndexBuffer[g_FrameIndex] || g_IndexBufferSize[g_FrameIndex] < index_size)
{
if (g_IndexBuffer[g_FrameIndex])
vkDestroyBuffer(g_Device, g_IndexBuffer[g_FrameIndex], g_Allocator);
if (g_IndexBufferMemory[g_FrameIndex])
vkFreeMemory(g_Device, g_IndexBufferMemory[g_FrameIndex], g_Allocator);
size_t index_buffer_size = ((index_size-1) / g_BufferMemoryAlignment+1) * g_BufferMemoryAlignment;
VkBufferCreateInfo buffer_info = {};
buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
buffer_info.size = index_buffer_size;
buffer_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
err = vkCreateBuffer(g_Device, &buffer_info, g_Allocator, &g_IndexBuffer[g_FrameIndex]);
ImGui_ImplGlfwVulkan_VkResult(err);
VkMemoryRequirements req;
vkGetBufferMemoryRequirements(g_Device, g_IndexBuffer[g_FrameIndex], &req);
g_BufferMemoryAlignment = (g_BufferMemoryAlignment > req.alignment) ? g_BufferMemoryAlignment : req.alignment;
VkMemoryAllocateInfo alloc_info = {};
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
alloc_info.allocationSize = req.size;
alloc_info.memoryTypeIndex = ImGui_ImplGlfwVulkan_MemoryType(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, req.memoryTypeBits);
err = vkAllocateMemory(g_Device, &alloc_info, g_Allocator, &g_IndexBufferMemory[g_FrameIndex]);
ImGui_ImplGlfwVulkan_VkResult(err);
err = vkBindBufferMemory(g_Device, g_IndexBuffer[g_FrameIndex], g_IndexBufferMemory[g_FrameIndex], 0);
ImGui_ImplGlfwVulkan_VkResult(err);
g_IndexBufferSize[g_FrameIndex] = index_buffer_size;
}
// Upload Vertex and index Data:
{
ImDrawVert* vtx_dst;
ImDrawIdx* idx_dst;
err = vkMapMemory(g_Device, g_VertexBufferMemory[g_FrameIndex], 0, vertex_size, 0, (void**)(&vtx_dst));
ImGui_ImplGlfwVulkan_VkResult(err);
err = vkMapMemory(g_Device, g_IndexBufferMemory[g_FrameIndex], 0, index_size, 0, (void**)(&idx_dst));
ImGui_ImplGlfwVulkan_VkResult(err);
for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
memcpy(vtx_dst, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert));
memcpy(idx_dst, &cmd_list->IdxBuffer[0], cmd_list->IdxBuffer.size() * sizeof(ImDrawIdx));
vtx_dst += cmd_list->VtxBuffer.size();
idx_dst += cmd_list->IdxBuffer.size();
}
VkMappedMemoryRange range[2] = {};
range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
range[0].memory = g_VertexBufferMemory[g_FrameIndex];
range[0].size = vertex_size;
range[1].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
range[1].memory = g_IndexBufferMemory[g_FrameIndex];
range[1].size = index_size;
err = vkFlushMappedMemoryRanges(g_Device, 2, range);
ImGui_ImplGlfwVulkan_VkResult(err);
vkUnmapMemory(g_Device, g_VertexBufferMemory[g_FrameIndex]);
vkUnmapMemory(g_Device, g_IndexBufferMemory[g_FrameIndex]);
}
// Bind pipeline and descriptor sets:
{
vkCmdBindPipeline(g_CommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_Pipeline);
VkDescriptorSet desc_set[1] = {g_DescriptorSet};
vkCmdBindDescriptorSets(g_CommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_PipelineLayout, 0, 1, desc_set, 0, NULL);
}
// Bind Vertex And Index Buffer:
{
VkBuffer vertex_buffers[1] = {g_VertexBuffer[g_FrameIndex]};
VkDeviceSize vertex_offset[1] = {0};
vkCmdBindVertexBuffers(g_CommandBuffer, 0, 1, vertex_buffers, vertex_offset);
vkCmdBindIndexBuffer(g_CommandBuffer, g_IndexBuffer[g_FrameIndex], 0, VK_INDEX_TYPE_UINT16);
}
// Setup viewport:
{
VkViewport viewport;
viewport.x = 0;
viewport.y = 0;
viewport.width = ImGui::GetIO().DisplaySize.x;
viewport.height = ImGui::GetIO().DisplaySize.y;
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
vkCmdSetViewport(g_CommandBuffer, 0, 1, &viewport);
}
// Setup scale and translation:
{
float scale[2];
scale[0] = 2.0f/io.DisplaySize.x;
scale[1] = 2.0f/io.DisplaySize.y;
float translate[2];
translate[0] = -1.0f;
translate[1] = -1.0f;
vkCmdPushConstants(g_CommandBuffer, g_PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, sizeof(float) * 0, sizeof(float) * 2, scale);
vkCmdPushConstants(g_CommandBuffer, g_PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, sizeof(float) * 2, sizeof(float) * 2, translate);
}
// Render the command lists:
int vtx_offset = 0;
int idx_offset = 0;
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)
{
pcmd->UserCallback(cmd_list, pcmd);
}
else
{
VkRect2D scissor;
scissor.offset.x = static_cast<int32_t>(pcmd->ClipRect.x);
scissor.offset.y = static_cast<int32_t>(pcmd->ClipRect.y);
scissor.extent.width = static_cast<uint32_t>(pcmd->ClipRect.z - pcmd->ClipRect.x);
scissor.extent.height = static_cast<uint32_t>(pcmd->ClipRect.w - pcmd->ClipRect.y + 1); // TODO: + 1??????
vkCmdSetScissor(g_CommandBuffer, 0, 1, &scissor);
vkCmdDrawIndexed(g_CommandBuffer, pcmd->ElemCount, 1, idx_offset, vtx_offset, 0);
}
idx_offset += pcmd->ElemCount;
}
vtx_offset += cmd_list->VtxBuffer.size();
}
}
static const char* ImGui_ImplGlfwVulkan_GetClipboardText()
{
return glfwGetClipboardString(g_Window);
}
static void ImGui_ImplGlfwVulkan_SetClipboardText(const char* text)
{
glfwSetClipboardString(g_Window, text);
}
void ImGui_ImplGlfwVulkan_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/)
{
if (action == GLFW_PRESS && button >= 0 && button < 3)
g_MousePressed[button] = true;
}
void ImGui_ImplGlfwVulkan_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset)
{
g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines.
}
void ImGui_ImplGlfwVulkan_KeyCallback(GLFWwindow*, int key, int, int action, int mods)
{
ImGuiIO& io = ImGui::GetIO();
if (action == GLFW_PRESS)
io.KeysDown[key] = true;
if (action == GLFW_RELEASE)
io.KeysDown[key] = false;
(void)mods; // Modifiers are not reliable across systems
io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL];
io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT];
io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT];
io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER];
}
void ImGui_ImplGlfwVulkan_CharCallback(GLFWwindow*, unsigned int c)
{
ImGuiIO& io = ImGui::GetIO();
if (c > 0 && c < 0x10000)
io.AddInputCharacter((unsigned short)c);
}
bool ImGui_ImplGlfwVulkan_CreateFontsTexture(VkCommandBuffer command_buffer)
{
ImGuiIO& io = ImGui::GetIO();
unsigned char* pixels;
int width, height;
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
size_t upload_size = width*height*4*sizeof(char);
VkResult err;
// Create the Image:
{
VkImageCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
info.imageType = VK_IMAGE_TYPE_2D;
info.format = VK_FORMAT_R8G8B8A8_UNORM;
info.extent.width = width;
info.extent.height = height;
info.extent.depth = 1;
info.mipLevels = 1;
info.arrayLayers = 1;
info.samples = VK_SAMPLE_COUNT_1_BIT;
info.tiling = VK_IMAGE_TILING_OPTIMAL;
info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
err = vkCreateImage(g_Device, &info, g_Allocator, &g_FontImage);
ImGui_ImplGlfwVulkan_VkResult(err);
VkMemoryRequirements req;
vkGetImageMemoryRequirements(g_Device, g_FontImage, &req);
VkMemoryAllocateInfo alloc_info = {};
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
alloc_info.allocationSize = req.size;
alloc_info.memoryTypeIndex = ImGui_ImplGlfwVulkan_MemoryType(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, req.memoryTypeBits);
err = vkAllocateMemory(g_Device, &alloc_info, g_Allocator, &g_FontMemory);
ImGui_ImplGlfwVulkan_VkResult(err);
err = vkBindImageMemory(g_Device, g_FontImage, g_FontMemory, 0);
ImGui_ImplGlfwVulkan_VkResult(err);
}
// Create the Image View:
{
VkResult err;
VkImageViewCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
info.image = g_FontImage;
info.viewType = VK_IMAGE_VIEW_TYPE_2D;
info.format = VK_FORMAT_R8G8B8A8_UNORM;
info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
info.subresourceRange.levelCount = 1;
info.subresourceRange.layerCount = 1;
err = vkCreateImageView(g_Device, &info, g_Allocator, &g_FontView);
ImGui_ImplGlfwVulkan_VkResult(err);
}
// Update the Descriptor Set:
{
VkDescriptorImageInfo desc_image[1] = {};
desc_image[0].sampler = g_FontSampler;
desc_image[0].imageView = g_FontView;
desc_image[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
VkWriteDescriptorSet write_desc[1] = {};
write_desc[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
write_desc[0].dstSet = g_DescriptorSet;
write_desc[0].descriptorCount = 1;
write_desc[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
write_desc[0].pImageInfo = desc_image;
vkUpdateDescriptorSets(g_Device, 1, write_desc, 0, NULL);
}
// Create the Upload Buffer:
{
VkBufferCreateInfo buffer_info = {};
buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
buffer_info.size = upload_size;
buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
err = vkCreateBuffer(g_Device, &buffer_info, g_Allocator, &g_UploadBuffer);
ImGui_ImplGlfwVulkan_VkResult(err);
VkMemoryRequirements req;
vkGetBufferMemoryRequirements(g_Device, g_UploadBuffer, &req);
g_BufferMemoryAlignment = (g_BufferMemoryAlignment > req.alignment) ? g_BufferMemoryAlignment : req.alignment;
VkMemoryAllocateInfo alloc_info = {};
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
alloc_info.allocationSize = req.size;
alloc_info.memoryTypeIndex = ImGui_ImplGlfwVulkan_MemoryType(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, req.memoryTypeBits);
err = vkAllocateMemory(g_Device, &alloc_info, g_Allocator, &g_UploadBufferMemory);
ImGui_ImplGlfwVulkan_VkResult(err);
err = vkBindBufferMemory(g_Device, g_UploadBuffer, g_UploadBufferMemory, 0);
ImGui_ImplGlfwVulkan_VkResult(err);
}
// Upload to Buffer:
{
char* map = NULL;
err = vkMapMemory(g_Device, g_UploadBufferMemory, 0, upload_size, 0, (void**)(&map));
ImGui_ImplGlfwVulkan_VkResult(err);
memcpy(map, pixels, upload_size);
VkMappedMemoryRange range[1] = {};
range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
range[0].memory = g_UploadBufferMemory;
range[0].size = upload_size;
err = vkFlushMappedMemoryRanges(g_Device, 1, range);
ImGui_ImplGlfwVulkan_VkResult(err);
vkUnmapMemory(g_Device, g_UploadBufferMemory);
}
// Copy to Image:
{
VkImageMemoryBarrier copy_barrier[1] = {};
copy_barrier[0].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
copy_barrier[0].dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
copy_barrier[0].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
copy_barrier[0].newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
copy_barrier[0].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
copy_barrier[0].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
copy_barrier[0].image = g_FontImage;
copy_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copy_barrier[0].subresourceRange.levelCount = 1;
copy_barrier[0].subresourceRange.layerCount = 1;
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1, copy_barrier);
VkBufferImageCopy region = {};
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.imageSubresource.layerCount = 1;
region.imageExtent.width = width;
region.imageExtent.height = height;
vkCmdCopyBufferToImage(command_buffer, g_UploadBuffer, g_FontImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
VkImageMemoryBarrier use_barrier[1] = {};
use_barrier[0].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
use_barrier[0].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
use_barrier[0].dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
use_barrier[0].oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
use_barrier[0].newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
use_barrier[0].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
use_barrier[0].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
use_barrier[0].image = g_FontImage;
use_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
use_barrier[0].subresourceRange.levelCount = 1;
use_barrier[0].subresourceRange.layerCount = 1;
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, NULL, 0, NULL, 1, use_barrier);
}
// Store our identifier
io.Fonts->TexID = (void *)(intptr_t)g_FontImage;
return true;
}
bool ImGui_ImplGlfwVulkan_CreateDeviceObjects()
{
VkResult err;
VkShaderModule vert_module;
VkShaderModule frag_module;
// Create The Shader Modules:
{
VkShaderModuleCreateInfo vert_info = {};
vert_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
vert_info.codeSize = __glsl_shader_vert_spv_len;
vert_info.pCode = (uint32_t*)__glsl_shader_vert_spv;
err = vkCreateShaderModule(g_Device, &vert_info, g_Allocator, &vert_module);
ImGui_ImplGlfwVulkan_VkResult(err);
VkShaderModuleCreateInfo frag_info = {};
frag_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
frag_info.codeSize = __glsl_shader_frag_spv_len;
frag_info.pCode = (uint32_t*)__glsl_shader_frag_spv;
err = vkCreateShaderModule(g_Device, &frag_info, g_Allocator, &frag_module);
ImGui_ImplGlfwVulkan_VkResult(err);
}
if (!g_FontSampler)
{
VkSamplerCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
info.magFilter = VK_FILTER_LINEAR;
info.minFilter = VK_FILTER_LINEAR;
info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
info.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
info.minLod = -1000;
info.maxLod = 1000;
err = vkCreateSampler(g_Device, &info, g_Allocator, &g_FontSampler);
ImGui_ImplGlfwVulkan_VkResult(err);
}
if (!g_DescriptorSetLayout)
{
VkSampler sampler[1] = {g_FontSampler};
VkDescriptorSetLayoutBinding binding[1] = {};
binding[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
binding[0].descriptorCount = 1;
binding[0].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
binding[0].pImmutableSamplers = sampler;
VkDescriptorSetLayoutCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
info.bindingCount = 1;
info.pBindings = binding;
err = vkCreateDescriptorSetLayout(g_Device, &info, g_Allocator, &g_DescriptorSetLayout);
ImGui_ImplGlfwVulkan_VkResult(err);
}
// Create Descriptor Set:
{
VkDescriptorSetAllocateInfo alloc_info = {};
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
alloc_info.descriptorPool = g_DescriptorPool;
alloc_info.descriptorSetCount = 1;
alloc_info.pSetLayouts = &g_DescriptorSetLayout;
err = vkAllocateDescriptorSets(g_Device, &alloc_info, &g_DescriptorSet);
ImGui_ImplGlfwVulkan_VkResult(err);
}
if (!g_PipelineLayout)
{
VkPushConstantRange push_constants[2] = {};
push_constants[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
push_constants[0].offset = sizeof(float) * 0;
push_constants[0].size = sizeof(float) * 2;
push_constants[1].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
push_constants[1].offset = sizeof(float) * 2;
push_constants[1].size = sizeof(float) * 2;
VkDescriptorSetLayout set_layout[1] = {g_DescriptorSetLayout};
VkPipelineLayoutCreateInfo layout_info = {};
layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
layout_info.setLayoutCount = 1;
layout_info.pSetLayouts = set_layout;
layout_info.pushConstantRangeCount = 2;
layout_info.pPushConstantRanges = push_constants;
err = vkCreatePipelineLayout(g_Device, &layout_info, g_Allocator, &g_PipelineLayout);
ImGui_ImplGlfwVulkan_VkResult(err);
}
VkPipelineShaderStageCreateInfo stage[2] = {};
stage[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
stage[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
stage[0].module = vert_module;
stage[0].pName = "main";
stage[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
stage[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
stage[1].module = frag_module;
stage[1].pName = "main";
VkVertexInputBindingDescription binding_desc[1] = {};
binding_desc[0].stride = sizeof(ImDrawVert);
binding_desc[0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
VkVertexInputAttributeDescription attribute_desc[3] = {};
attribute_desc[0].location = 0;
attribute_desc[0].binding = binding_desc[0].binding;
attribute_desc[0].format = VK_FORMAT_R32G32_SFLOAT;
attribute_desc[0].offset = (size_t)(&((ImDrawVert*)0)->pos);
attribute_desc[1].location = 1;
attribute_desc[1].binding = binding_desc[0].binding;
attribute_desc[1].format = VK_FORMAT_R32G32_SFLOAT;
attribute_desc[1].offset = (size_t)(&((ImDrawVert*)0)->uv);
attribute_desc[2].location = 2;
attribute_desc[2].binding = binding_desc[0].binding;
attribute_desc[2].format = VK_FORMAT_R8G8B8A8_UNORM;
attribute_desc[2].offset = (size_t)(&((ImDrawVert*)0)->col);
VkPipelineVertexInputStateCreateInfo vertex_info = {};
vertex_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
vertex_info.vertexBindingDescriptionCount = 1;
vertex_info.pVertexBindingDescriptions = binding_desc;
vertex_info.vertexAttributeDescriptionCount = 3;
vertex_info.pVertexAttributeDescriptions = attribute_desc;
VkPipelineInputAssemblyStateCreateInfo ia_info = {};
ia_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
ia_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
VkPipelineViewportStateCreateInfo viewport_info = {};
viewport_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
viewport_info.viewportCount = 1;
viewport_info.scissorCount = 1;
VkPipelineRasterizationStateCreateInfo raster_info = {};
raster_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
raster_info.polygonMode = VK_POLYGON_MODE_FILL;
raster_info.cullMode = VK_CULL_MODE_NONE;
raster_info.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
VkPipelineMultisampleStateCreateInfo ms_info = {};
ms_info.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
ms_info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
VkPipelineColorBlendAttachmentState color_attachment[1] = {};
color_attachment[0].blendEnable = VK_TRUE;
color_attachment[0].srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
color_attachment[0].dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
color_attachment[0].colorBlendOp = VK_BLEND_OP_ADD;
color_attachment[0].srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
color_attachment[0].dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
color_attachment[0].alphaBlendOp = VK_BLEND_OP_ADD;
color_attachment[0].colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
VkPipelineColorBlendStateCreateInfo blend_info = {};
blend_info.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
blend_info.attachmentCount = 1;
blend_info.pAttachments = color_attachment;
VkDynamicState dynamic_states[2] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
VkPipelineDynamicStateCreateInfo dynamic_state = {};
dynamic_state.dynamicStateCount = 2;
dynamic_state.pDynamicStates = dynamic_states;
VkGraphicsPipelineCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
info.flags = g_PipelineCreateFlags;
info.stageCount = 2;
info.pStages = stage;
info.pVertexInputState = &vertex_info;
info.pInputAssemblyState = &ia_info;
info.pViewportState = &viewport_info;
info.pRasterizationState = &raster_info;
info.pMultisampleState = &ms_info;
info.pColorBlendState = &blend_info;
info.pDynamicState = &dynamic_state;
info.layout = g_PipelineLayout;
info.renderPass = g_RenderPass;
err = vkCreateGraphicsPipelines(g_Device, g_PipelineCache, 1, &info, g_Allocator, &g_Pipeline);
ImGui_ImplGlfwVulkan_VkResult(err);
vkDestroyShaderModule(g_Device, vert_module, g_Allocator);
vkDestroyShaderModule(g_Device, frag_module, g_Allocator);
return true;
}
void ImGui_ImplGlfwVulkan_InvalidateFontUploadObjects()
{
if (g_UploadBuffer)
{
vkDestroyBuffer(g_Device, g_UploadBuffer, g_Allocator);
g_UploadBuffer = VK_NULL_HANDLE;
}
if (g_UploadBufferMemory)
{
vkFreeMemory(g_Device, g_UploadBufferMemory, g_Allocator);
g_UploadBufferMemory = VK_NULL_HANDLE;
}
}
void ImGui_ImplGlfwVulkan_InvalidateDeviceObjects()
{
ImGui_ImplGlfwVulkan_InvalidateFontUploadObjects();
for (int i=0; i<IMGUI_VK_QUEUED_FRAMES; i++)
{
if (g_VertexBuffer[i])
vkDestroyBuffer(g_Device, g_VertexBuffer[i], g_Allocator);
if (g_VertexBufferMemory[i])
vkFreeMemory(g_Device, g_VertexBufferMemory[i], g_Allocator);
if (g_IndexBuffer[i])
vkDestroyBuffer(g_Device, g_IndexBuffer[i], g_Allocator);
if (g_IndexBufferMemory[i])
vkFreeMemory(g_Device, g_IndexBufferMemory[i], g_Allocator);
}
if (g_FontView)
vkDestroyImageView(g_Device, g_FontView, g_Allocator);
if (g_FontImage)
vkDestroyImage(g_Device, g_FontImage, g_Allocator);
if (g_FontMemory)
vkFreeMemory(g_Device, g_FontMemory, g_Allocator);
if (g_FontSampler)
vkDestroySampler(g_Device, g_FontSampler, g_Allocator);
if (g_DescriptorSetLayout)
vkDestroyDescriptorSetLayout(g_Device, g_DescriptorSetLayout, g_Allocator);
if (g_PipelineLayout)
vkDestroyPipelineLayout(g_Device, g_PipelineLayout, g_Allocator);
if (g_Pipeline)
vkDestroyPipeline(g_Device, g_Pipeline, g_Allocator);
}
bool ImGui_ImplGlfwVulkan_Init(GLFWwindow* window, bool install_callbacks, ImGui_ImplGlfwVulkan_Init_Data *init_data)
{
g_Allocator = init_data->allocator;
g_Gpu = init_data->gpu;
g_Device = init_data->device;
g_RenderPass = init_data->render_pass;
g_PipelineCache = init_data->pipeline_cache;
g_DescriptorPool = init_data->descriptor_pool;
g_CheckVkResult = init_data->check_vk_result;
g_Window = window;
ImGuiIO& io = ImGui::GetIO();
io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT;
io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT;
io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP;
io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN;
io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP;
io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN;
io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME;
io.KeyMap[ImGuiKey_End] = GLFW_KEY_END;
io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE;
io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE;
io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER;
io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE;
io.KeyMap[ImGuiKey_A] = GLFW_KEY_A;
io.KeyMap[ImGuiKey_C] = GLFW_KEY_C;
io.KeyMap[ImGuiKey_V] = GLFW_KEY_V;
io.KeyMap[ImGuiKey_X] = GLFW_KEY_X;
io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y;
io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z;
io.RenderDrawListsFn = ImGui_ImplGlfwVulkan_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer.
io.SetClipboardTextFn = ImGui_ImplGlfwVulkan_SetClipboardText;
io.GetClipboardTextFn = ImGui_ImplGlfwVulkan_GetClipboardText;
#ifdef _WIN32
io.ImeWindowHandle = glfwGetWin32Window(g_Window);
#endif
if (install_callbacks)
{
glfwSetMouseButtonCallback(window, ImGui_ImplGlfwVulkan_MouseButtonCallback);
glfwSetScrollCallback(window, ImGui_ImplGlfwVulkan_ScrollCallback);
glfwSetKeyCallback(window, ImGui_ImplGlfwVulkan_KeyCallback);
glfwSetCharCallback(window, ImGui_ImplGlfwVulkan_CharCallback);
}
ImGui_ImplGlfwVulkan_CreateDeviceObjects();
return true;
}
void ImGui_ImplGlfwVulkan_Shutdown()
{
ImGui_ImplGlfwVulkan_InvalidateDeviceObjects();
ImGui::Shutdown();
}
void ImGui_ImplGlfwVulkan_NewFrame()
{
ImGuiIO& io = ImGui::GetIO();
// Setup display size (every frame to accommodate for window resizing)
int w, h;
int display_w, display_h;
glfwGetWindowSize(g_Window, &w, &h);
glfwGetFramebufferSize(g_Window, &display_w, &display_h);
io.DisplaySize = ImVec2((float)w, (float)h);
io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0);
// Setup time step
double current_time = glfwGetTime();
io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f);
g_Time = current_time;
// Setup inputs
// (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents())
if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED))
{
double mouse_x, mouse_y;
glfwGetCursorPos(g_Window, &mouse_x, &mouse_y);
io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.)
}
else
{
io.MousePos = ImVec2(-1,-1);
}
for (int i = 0; i < 3; i++)
{
io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.
g_MousePressed[i] = false;
}
io.MouseWheel = g_MouseWheel;
g_MouseWheel = 0.0f;
// Hide OS mouse cursor if ImGui is drawing it
glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL);
// Start the frame
ImGui::NewFrame();
}
void ImGui_ImplGlfwVulkan_Render(VkCommandBuffer command_buffer)
{
g_CommandBuffer = command_buffer;
ImGui::Render();
g_CommandBuffer = VK_NULL_HANDLE;
g_FrameIndex = (g_FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES;
}

View File

@ -0,0 +1,40 @@
// ImGui GLFW binding with Vulkan + shaders
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 5 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXX_CreateFontsTexture(), ImGui_ImplXXXX_NewFrame(), ImGui_ImplXXXX_Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
// https://github.com/ocornut/imgui
struct GLFWwindow;
#define IMGUI_VK_QUEUED_FRAMES 2
struct ImGui_ImplGlfwVulkan_Init_Data
{
VkAllocationCallbacks* allocator;
VkPhysicalDevice gpu;
VkDevice device;
VkRenderPass render_pass;
VkPipelineCache pipeline_cache;
VkDescriptorPool descriptor_pool;
void (*check_vk_result)(VkResult err);
};
IMGUI_API bool ImGui_ImplGlfwVulkan_Init(GLFWwindow* window, bool install_callbacks, ImGui_ImplGlfwVulkan_Init_Data *init_data);
IMGUI_API void ImGui_ImplGlfwVulkan_Shutdown();
IMGUI_API void ImGui_ImplGlfwVulkan_NewFrame();
IMGUI_API void ImGui_ImplGlfwVulkan_Render(VkCommandBuffer command_buffer);
// Use if you want to reset your rendering device without losing ImGui state.
IMGUI_API void ImGui_ImplGlfwVulkan_InvalidateFontUploadObjects();
IMGUI_API void ImGui_ImplGlfwVulkan_InvalidateDeviceObjects();
IMGUI_API bool ImGui_ImplGlfwVulkan_CreateFontsTexture(VkCommandBuffer command_buffer);
IMGUI_API bool ImGui_ImplGlfwVulkan_CreateDeviceObjects();
// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization)
// Provided here if you want to chain callbacks.
// You can also handle inputs yourself and use those as a reference.
IMGUI_API void ImGui_ImplGlfwVulkan_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods);
IMGUI_API void ImGui_ImplGlfwVulkan_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset);
IMGUI_API void ImGui_ImplGlfwVulkan_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
IMGUI_API void ImGui_ImplGlfwVulkan_CharCallback(GLFWwindow* window, unsigned int c);

View File

@ -0,0 +1,539 @@
// ImGui - standalone example application for Glfw + Vulkan, using programmable pipeline
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
#include <imgui.h>
#include <stdio.h> // printf, fprintf
#include <stdlib.h> // abort
#define GLFW_INCLUDE_NONE
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
#include "imgui_impl_glfw_vulkan.h"
#define IMGUI_MAX_POSSIBLE_BACK_BUFFERS 16
static VkAllocationCallbacks* g_Allocator = NULL;
static VkInstance g_Instance = VK_NULL_HANDLE;
static VkSurfaceKHR g_Surface = VK_NULL_HANDLE;
static VkPhysicalDevice g_Gpu = VK_NULL_HANDLE;
static VkDevice g_Device = VK_NULL_HANDLE;
static VkSwapchainKHR g_Swapchain = VK_NULL_HANDLE;
static VkRenderPass g_RenderPass = VK_NULL_HANDLE;
static uint32_t g_QueueFamily = 0;
static VkQueue g_Queue = VK_NULL_HANDLE;
static VkFormat g_Format = VK_FORMAT_B8G8R8A8_UNORM;
static VkColorSpaceKHR g_ColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
static VkImageSubresourceRange g_ImageRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE;
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
static int fb_width, fb_height;
static uint32_t g_BackBufferIndex = 0;
static uint32_t g_BackBufferCount = 0;
static VkImage g_BackBuffer[IMGUI_MAX_POSSIBLE_BACK_BUFFERS] = {};
static VkImageView g_BackBufferView[IMGUI_MAX_POSSIBLE_BACK_BUFFERS] = {};
static VkFramebuffer g_Framebuffer[IMGUI_MAX_POSSIBLE_BACK_BUFFERS] = {};
static uint32_t g_FrameIndex = 0;
static VkCommandPool g_CommandPool[IMGUI_VK_QUEUED_FRAMES];
static VkCommandBuffer g_CommandBuffer[IMGUI_VK_QUEUED_FRAMES];
static VkFence g_Fence[IMGUI_VK_QUEUED_FRAMES];
static VkSemaphore g_Semaphore[IMGUI_VK_QUEUED_FRAMES];
static VkClearValue g_ClearValue = {};
static void check_vk_result(VkResult err)
{
if (err == 0) return;
printf("VkResult %d\n", err);
if (err < 0)
abort();
}
static void resize_vulkan(GLFWwindow* /*window*/, int w, int h)
{
VkResult err;
VkSwapchainKHR old_swapchain = g_Swapchain;
err = vkDeviceWaitIdle(g_Device);
check_vk_result(err);
// Destroy old Framebuffer:
for (uint32_t i=0; i<g_BackBufferCount; i++)
if (g_BackBufferView[i])
vkDestroyImageView(g_Device, g_BackBufferView[i], g_Allocator);
for(uint32_t i=0; i<g_BackBufferCount; i++)
if (g_Framebuffer[i])
vkDestroyFramebuffer(g_Device, g_Framebuffer[i], g_Allocator);
if (g_RenderPass)
vkDestroyRenderPass(g_Device, g_RenderPass, g_Allocator);
// Create Swapchain:
{
VkSwapchainCreateInfoKHR info = {};
info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
info.surface = g_Surface;
info.imageFormat = g_Format;
info.imageColorSpace = g_ColorSpace;
info.imageArrayLayers = 1;
info.imageUsage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
info.presentMode = VK_PRESENT_MODE_FIFO_KHR;
info.clipped = VK_TRUE;
info.oldSwapchain = old_swapchain;
VkSurfaceCapabilitiesKHR cap;
err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(g_Gpu, g_Surface, &cap);
check_vk_result(err);
info.minImageCount = (cap.minImageCount + 2 < cap.maxImageCount) ? (cap.minImageCount + 2) : cap.maxImageCount;
if (cap.currentExtent.width == 0xffffffff)
{
fb_width = w;
fb_height = h;
info.imageExtent.width = fb_width;
info.imageExtent.height = fb_height;
}
else
{
fb_width = cap.currentExtent.width;
fb_height = cap.currentExtent.height;
info.imageExtent.width = fb_width;
info.imageExtent.height = fb_height;
}
err = vkCreateSwapchainKHR(g_Device, &info, g_Allocator, &g_Swapchain);
check_vk_result(err);
err = vkGetSwapchainImagesKHR(g_Device, g_Swapchain, &g_BackBufferCount, NULL);
check_vk_result(err);
err = vkGetSwapchainImagesKHR(g_Device, g_Swapchain, &g_BackBufferCount, g_BackBuffer);
check_vk_result(err);
}
if (old_swapchain)
vkDestroySwapchainKHR(g_Device, old_swapchain, g_Allocator);
// Create the Render Pass:
{
VkAttachmentDescription attachment = {};
attachment.format = g_Format;
attachment.samples = VK_SAMPLE_COUNT_1_BIT;
attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
attachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkAttachmentReference color_attachment = {};
color_attachment.attachment = 0;
color_attachment.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkSubpassDescription subpass = {};
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass.colorAttachmentCount = 1;
subpass.pColorAttachments = &color_attachment;
VkRenderPassCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
info.attachmentCount = 1;
info.pAttachments = &attachment;
info.subpassCount = 1;
info.pSubpasses = &subpass;
err = vkCreateRenderPass(g_Device, &info, g_Allocator, &g_RenderPass);
check_vk_result(err);
}
// Create The Image Views
{
VkImageViewCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
info.viewType = VK_IMAGE_VIEW_TYPE_2D;
info.format = g_Format;
info.components.r = VK_COMPONENT_SWIZZLE_R;
info.components.g = VK_COMPONENT_SWIZZLE_G;
info.components.b = VK_COMPONENT_SWIZZLE_B;
info.components.a = VK_COMPONENT_SWIZZLE_A;
info.subresourceRange = g_ImageRange;
for (uint32_t i = 0; i<g_BackBufferCount; i++)
{
info.image = g_BackBuffer[i];
err = vkCreateImageView(g_Device, &info, g_Allocator, &g_BackBufferView[i]);
check_vk_result(err);
}
}
// Create Framebuffer:
{
VkImageView attachment[1];
VkFramebufferCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
info.renderPass = g_RenderPass;
info.attachmentCount = 1;
info.pAttachments = attachment;
info.width = fb_width;
info.height = fb_height;
info.layers = 1;
for (uint32_t i = 0; i<g_BackBufferCount; i++)
{
attachment[0] = g_BackBufferView[i];
err = vkCreateFramebuffer(g_Device, &info, g_Allocator, &g_Framebuffer[i]);
check_vk_result(err);
}
}
}
static void setup_vulkan(GLFWwindow* window)
{
VkResult err;
// Create Vulkan Instance
{
uint32_t glfw_extensions_count;
const char** glfw_extensions = glfwGetRequiredInstanceExtensions(&glfw_extensions_count);
VkInstanceCreateInfo create_info = {};
create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
create_info.enabledExtensionCount = glfw_extensions_count;
create_info.ppEnabledExtensionNames = glfw_extensions;
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
check_vk_result(err);
}
// Create Window Surface
{
err = glfwCreateWindowSurface(g_Instance, window, g_Allocator, &g_Surface);
check_vk_result(err);
}
// Get GPU
{
uint32_t count = 1;
err = vkEnumeratePhysicalDevices(g_Instance, &count, &g_Gpu);
check_vk_result(err);
}
// Create Logical Device
{
int device_extension_count = 1;
const char* device_extensions[] = {"VK_KHR_swapchain"};
const uint32_t queue_index = 0;
const uint32_t queue_count = 1;
const float queue_priority[] = {1.0f};
VkDeviceQueueCreateInfo queue_info[1] = {};
queue_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queue_info[0].queueFamilyIndex = g_QueueFamily;
queue_info[0].queueCount = queue_count;
queue_info[0].pQueuePriorities = queue_priority;
VkDeviceCreateInfo create_info = {};
create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
create_info.queueCreateInfoCount = sizeof(queue_info)/sizeof(queue_info[0]);
create_info.pQueueCreateInfos = queue_info;
create_info.enabledExtensionCount = device_extension_count;
create_info.ppEnabledExtensionNames = device_extensions;
err = vkCreateDevice(g_Gpu, &create_info, g_Allocator, &g_Device);
check_vk_result(err);
vkGetDeviceQueue(g_Device, g_QueueFamily, queue_index, &g_Queue);
}
// Create Framebuffers
{
int w, h;
glfwGetFramebufferSize(window, &w, &h);
resize_vulkan(window, w, h);
glfwSetFramebufferSizeCallback(window, resize_vulkan);
}
// Create Command Buffers
for (int i=0; i<IMGUI_VK_QUEUED_FRAMES; i++)
{
{
VkCommandPoolCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
info.queueFamilyIndex = g_QueueFamily;
err = vkCreateCommandPool(g_Device, &info, g_Allocator, &g_CommandPool[i]);
check_vk_result(err);
}
{
VkCommandBufferAllocateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
info.commandPool = g_CommandPool[i];
info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
info.commandBufferCount = 1;
err = vkAllocateCommandBuffers(g_Device, &info, &g_CommandBuffer[i]);
check_vk_result(err);
}
{
VkFenceCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
info.flags = VK_FENCE_CREATE_SIGNALED_BIT;
err = vkCreateFence(g_Device, &info, g_Allocator, &g_Fence[i]);
check_vk_result(err);
}
{
VkSemaphoreCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
err = vkCreateSemaphore(g_Device, &info, g_Allocator, &g_Semaphore[i]);
check_vk_result(err);
}
}
// Create Descriptor Pool
{
VkDescriptorPoolSize pool_size[11] =
{
{ VK_DESCRIPTOR_TYPE_SAMPLER, 1000 },
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 },
{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000 },
{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000 },
{ VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000 },
{ VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000 },
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000 },
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 },
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000 },
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000 },
{ VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000 }
};
VkDescriptorPoolCreateInfo pool_info = {};
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
pool_info.maxSets = 1000 * 11;
pool_info.poolSizeCount = 11;
pool_info.pPoolSizes = pool_size;
err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool);
check_vk_result(err);
}
}
static void cleanup_vulkan()
{
vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator);
for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++)
{
vkDestroyFence(g_Device, g_Fence[i], g_Allocator);
vkFreeCommandBuffers(g_Device, g_CommandPool[i], 1, &g_CommandBuffer[i]);
vkDestroyCommandPool(g_Device, g_CommandPool[i], g_Allocator);
vkDestroySemaphore(g_Device, g_Semaphore[i], g_Allocator);
}
for (uint32_t i = 0; i < g_BackBufferCount; i++)
{
vkDestroyImageView(g_Device, g_BackBufferView[i], g_Allocator);
vkDestroyFramebuffer(g_Device, g_Framebuffer[i], g_Allocator);
}
vkDestroyRenderPass(g_Device, g_RenderPass, g_Allocator);
vkDestroySwapchainKHR(g_Device, g_Swapchain, g_Allocator);
vkDestroySurfaceKHR(g_Instance, g_Surface, g_Allocator);
vkDestroyDevice(g_Device, g_Allocator);
vkDestroyInstance(g_Instance, g_Allocator);
}
static void frame_begin()
{
VkResult err;
while (true)
{
err = vkWaitForFences(g_Device, 1, &g_Fence[g_FrameIndex], VK_TRUE, 100);
if (err == VK_SUCCESS) break;
if (err == VK_TIMEOUT) continue;
check_vk_result(err);
}
{
err = vkAcquireNextImageKHR(g_Device, g_Swapchain, UINT64_MAX, g_Semaphore[g_FrameIndex], VK_NULL_HANDLE, &g_BackBufferIndex);
check_vk_result(err);
}
{
err = vkResetCommandPool(g_Device, g_CommandPool[g_FrameIndex], 0);
check_vk_result(err);
VkCommandBufferBeginInfo info = {};
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
err = vkBeginCommandBuffer(g_CommandBuffer[g_FrameIndex], &info);
check_vk_result(err);
}
{
VkRenderPassBeginInfo info = {};
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
info.renderPass = g_RenderPass;
info.framebuffer = g_Framebuffer[g_BackBufferIndex];
info.renderArea.extent.width = fb_width;
info.renderArea.extent.height = fb_height;
info.clearValueCount = 1;
info.pClearValues = &g_ClearValue;
vkCmdBeginRenderPass(g_CommandBuffer[g_FrameIndex], &info, VK_SUBPASS_CONTENTS_INLINE);
}
}
static void frame_end()
{
VkResult err;
vkCmdEndRenderPass(g_CommandBuffer[g_FrameIndex]);
{
VkImageMemoryBarrier barrier = {};
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.image = g_BackBuffer[g_BackBufferIndex];
barrier.subresourceRange = g_ImageRange;
vkCmdPipelineBarrier(g_CommandBuffer[g_FrameIndex], VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, NULL, 0, NULL, 1, &barrier);
}
{
VkSubmitInfo info = {};
info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
info.waitSemaphoreCount = 1;
info.pWaitSemaphores = &g_Semaphore[g_FrameIndex];
info.commandBufferCount = 1;
info.pCommandBuffers = &g_CommandBuffer[g_FrameIndex];
err = vkEndCommandBuffer(g_CommandBuffer[g_FrameIndex]);
check_vk_result(err);
err = vkResetFences(g_Device, 1, &g_Fence[g_FrameIndex]);
check_vk_result(err);
err = vkQueueSubmit(g_Queue, 1, &info, g_Fence[g_FrameIndex]);
check_vk_result(err);
}
{
VkResult res;
VkSwapchainKHR swapchains[1] = {g_Swapchain};
uint32_t indices[1] = {g_BackBufferIndex};
VkPresentInfoKHR info = {};
info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
info.swapchainCount = 1;
info.pSwapchains = swapchains;
info.pImageIndices = indices;
info.pResults = &res;
err = vkQueuePresentKHR(g_Queue, &info);
check_vk_result(err);
check_vk_result(res);
}
g_FrameIndex = (g_FrameIndex) % IMGUI_VK_QUEUED_FRAMES;
}
static void error_callback(int error, const char* description)
{
fprintf(stderr, "Error %d: %s\n", error, description);
}
int main(int, char**)
{
// Setup window
glfwSetErrorCallback(error_callback);
if (!glfwInit())
return 1;
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui Vulkan example", NULL, NULL);
// Setup Vulkan
if (!glfwVulkanSupported())
{
printf("GLFW: Vulkan Not Supported\n");
return 1;
}
setup_vulkan(window);
// Setup ImGui binding
ImGui_ImplGlfwVulkan_Init_Data init_data = {};
init_data.allocator = g_Allocator;
init_data.gpu = g_Gpu;
init_data.device = g_Device;
init_data.render_pass = g_RenderPass;
init_data.pipeline_cache = g_PipelineCache;
init_data.descriptor_pool = g_DescriptorPool;
init_data.check_vk_result = check_vk_result;
ImGui_ImplGlfwVulkan_Init(window, true, &init_data);
// Load Fonts
// (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details)
//ImGuiIO& io = ImGui::GetIO();
//io.Fonts->AddFontDefault();
//io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f);
//io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f);
//io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f);
//io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f);
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese());
// Upload Fonts
{
VkResult err;
err = vkResetCommandPool(g_Device, g_CommandPool[g_FrameIndex], 0);
check_vk_result(err);
VkCommandBufferBeginInfo begin_info = {};
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
begin_info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
err = vkBeginCommandBuffer(g_CommandBuffer[g_FrameIndex], &begin_info);
check_vk_result(err);
ImGui_ImplGlfwVulkan_CreateFontsTexture(g_CommandBuffer[g_FrameIndex]);
VkSubmitInfo end_info = {};
end_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
end_info.commandBufferCount = 1;
end_info.pCommandBuffers = &g_CommandBuffer[g_FrameIndex];
err = vkEndCommandBuffer(g_CommandBuffer[g_FrameIndex]);
check_vk_result(err);
err = vkQueueSubmit(g_Queue, 1, &end_info, VK_NULL_HANDLE);
check_vk_result(err);
err = vkDeviceWaitIdle(g_Device);
check_vk_result(err);
ImGui_ImplGlfwVulkan_InvalidateFontUploadObjects();
}
bool show_test_window = true;
bool show_another_window = false;
ImVec4 clear_color = ImColor(114, 144, 154);
// Main loop
while (!glfwWindowShouldClose(window))
{
glfwPollEvents();
ImGui_ImplGlfwVulkan_NewFrame();
// 1. Show a simple window
// Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug"
{
static float f = 0.0f;
ImGui::Text("Hello, world!");
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
ImGui::ColorEdit3("clear color", (float*)&clear_color);
if (ImGui::Button("Test Window")) show_test_window ^= 1;
if (ImGui::Button("Another Window")) show_another_window ^= 1;
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
}
// 2. Show another simple window, this time using an explicit Begin/End pair
if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
ImGui::Text("Hello");
ImGui::End();
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
}
g_ClearValue.color.float32[0] = clear_color.x;
g_ClearValue.color.float32[1] = clear_color.y;
g_ClearValue.color.float32[2] = clear_color.z;
g_ClearValue.color.float32[3] = clear_color.w;
frame_begin();
ImGui_ImplGlfwVulkan_Render(g_CommandBuffer[g_FrameIndex]);
frame_end();
}
// Cleanup
VkResult err = vkDeviceWaitIdle(g_Device);
check_vk_result(err);
ImGui_ImplGlfwVulkan_Shutdown();
cleanup_vulkan();
glfwTerminate();
return 0;
}

View File

@ -1,6 +1,12 @@
The code in imgui.cpp embeds a copy of 'ProggyClean.ttf' that you can use without any external files. The code in imgui.cpp embeds a copy of 'ProggyClean.ttf' that you can use without any external files.
Those are only provided as a convenience, you can load your own .TTF files. The files in this folder are only provided as a convenience, you can use any of your own .TTF files.
Fonts are rasterized in a single texture at the time of calling either of io.Fonts.GetTexDataAsAlpha8()/GetTexDataAsRGBA32()/Build().
If you want to use icons in ImGui, a good idea is to merge an icon font within your main font, and refer to icons directly in your strings.
You can use headers files with definitions for popular icon fonts codepoints, by Juliette Foucaut, at https://github.com/juliettef/IconFontCppHeaders
--------------------------------- ---------------------------------
LOADING INSTRUCTIONS LOADING INSTRUCTIONS
@ -20,16 +26,23 @@
ImFontConfig config; ImFontConfig config;
config.OversampleH = 3; config.OversampleH = 3;
config.OversampleV = 3; config.OversampleV = 1;
config.GlyphExtraSpacing.x = 1.0f; config.GlyphExtraSpacing.x = 1.0f;
io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, &config); io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, &config);
If you have very large number of glyphs or multiple fonts:
- Mind the fact that some graphics drivers have texture size limitation.
- Set io.Fonts.TexDesiredWidth to specify a texture width to minimize texture height (see comment in ImFontAtlas::Build function).
- You may reduce oversampling, e.g. config.OversampleH = 2 or 1.
- Reduce glyphs ranges, consider calculating them based on your source data if this is possible.
Combine two fonts into one: Combine two fonts into one:
// Load main font // Load a first font
io.Fonts->AddFontDefault(); io.Fonts->AddFontDefault();
// Add character ranges and merge into main font // Add character ranges and merge into the previous font
// The ranges array is not copied by the AddFont* functions and is used lazily // The ranges array is not copied by the AddFont* functions and is used lazily
// so ensure it is available for duration of font usage // so ensure it is available for duration of font usage
static const ImWchar icons_ranges[] = { 0xf000, 0xf3ff, 0 }; // will not be copied by AddFont* so keep in scope. static const ImWchar icons_ranges[] = { 0xf000, 0xf3ff, 0 }; // will not be copied by AddFont* so keep in scope.
@ -54,6 +67,16 @@
ImFont* font = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels); ImFont* font = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels);
font->DisplayOffset.y += 1; // Render 1 pixel down font->DisplayOffset.y += 1; // Render 1 pixel down
---------------------------------
REMAP CODEPOINTS
---------------------------------
All your strings needs to use UTF-8 encoding. Specifying literal in your source code using a local code page (such as CP-923 for Japanese CP-1251 for Cyrillic) will not work.
In C++11 you can encode a string literal in UTF-8 by using the u8"hello" syntax. Otherwise you can convert yourself to UTF-8 or load text data from file already saved as UTF-8.
You can also try to remap your local codepage characters to their Unicode codepoint using font->AddRemapChar(), but international users may have problems reading/editing your source code.
--------------------------------- ---------------------------------
EMBED A FONT IN SOURCE CODE EMBED A FONT IN SOURCE CODE
--------------------------------- ---------------------------------
@ -66,8 +89,9 @@
ImFont* font = io.Fonts->AddFontFromMemoryCompressedBase85TTF(compressed_data_base85, size_pixels, ...); ImFont* font = io.Fonts->AddFontFromMemoryCompressedBase85TTF(compressed_data_base85, size_pixels, ...);
--------------------------------- ---------------------------------
INCLUDED FONT FILES FONT FILES INCLUDED IN THIS FOLDER
--------------------------------- ---------------------------------
Cousine-Regular.ttf Cousine-Regular.ttf
@ -93,6 +117,7 @@
Copyright (c) 2012, Jonathan Pinhorn Copyright (c) 2012, Jonathan Pinhorn
SIL OPEN FONT LICENSE Version 1.1 SIL OPEN FONT LICENSE Version 1.1
--------------------------------- ---------------------------------
LINKS LINKS
--------------------------------- ---------------------------------
@ -100,6 +125,7 @@
Icon fonts Icon fonts
https://fortawesome.github.io/Font-Awesome/ https://fortawesome.github.io/Font-Awesome/
https://github.com/SamBrishes/kenney-icon-font https://github.com/SamBrishes/kenney-icon-font
https://design.google.com/icons/
Typefaces for source code beautification Typefaces for source code beautification
https://github.com/chrissimpkins/codeface https://github.com/chrissimpkins/codeface

View File

@ -79,7 +79,6 @@ bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_b
if (use_base85_encoding) if (use_base85_encoding)
{ {
fprintf(out, "static const char %s_%sdata_base85[%d+1] =\n \"", symbol, compressed_str, (int)((compressed_sz+3)/4)*5); fprintf(out, "static const char %s_%sdata_base85[%d+1] =\n \"", symbol, compressed_str, (int)((compressed_sz+3)/4)*5);
int column = 0;
for (int i = 0; i < compressed_sz; i += 4) for (int i = 0; i < compressed_sz; i += 4)
{ {
unsigned int d = *(unsigned int*)(compressed + i); unsigned int d = *(unsigned int*)(compressed + i);

2631
imgui.cpp

File diff suppressed because it is too large Load Diff

488
imgui.h
View File

@ -1,4 +1,4 @@
// dear imgui, v1.47 // dear imgui, v1.49
// (headers) // (headers)
// See imgui.cpp file for documentation. // See imgui.cpp file for documentation.
@ -16,7 +16,12 @@
#include <stddef.h> // ptrdiff_t, NULL #include <stddef.h> // ptrdiff_t, NULL
#include <string.h> // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp #include <string.h> // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp
#define IMGUI_VERSION "1.47" #define IMGUI_VERSION "1.49"
// Define attributes of all API symbols declarations, e.g. for DLL under Windows.
#ifndef IMGUI_API
#define IMGUI_API
#endif
// Define assertion handler. // Define assertion handler.
#ifndef IM_ASSERT #ifndef IM_ASSERT
@ -24,51 +29,67 @@
#define IM_ASSERT(_EXPR) assert(_EXPR) #define IM_ASSERT(_EXPR) assert(_EXPR)
#endif #endif
// Define attributes of all API symbols declarations, e.g. for DLL under Windows. // Some compilers support applying printf-style warnings to user functions.
#ifndef IMGUI_API
#define IMGUI_API
#endif
#if defined(__clang__) || defined(__GNUC__) #if defined(__clang__) || defined(__GNUC__)
#define IM_PRINTFARGS(FMT) __attribute__((format(printf, FMT, (FMT+1)))) #define IM_PRINTFARGS(FMT) __attribute__((format(printf, FMT, (FMT+1))))
#else #else
#define IM_PRINTFARGS(FMT) #define IM_PRINTFARGS(FMT)
#endif #endif
// Forward declarations #if defined(__clang__)
struct ImDrawCmd; #pragma clang diagnostic push
struct ImDrawList; #pragma clang diagnostic ignored "-Wold-style-cast"
struct ImDrawData; #endif
struct ImFont;
struct ImFontAtlas;
struct ImColor;
struct ImGuiIO;
struct ImGuiStorage;
struct ImGuiStyle;
// Forward declarations
struct ImDrawChannel; // Temporary storage for outputting drawing commands out of order, used by ImDrawList::ChannelsSplit()
struct ImDrawCmd; // A single draw command within a parent ImDrawList (generally maps to 1 GPU draw call)
struct ImDrawData; // All draw command lists required to render the frame
struct ImDrawList; // A single draw command list (generally one per window)
struct ImDrawVert; // A single vertex (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 font loader
struct ImFontConfig; // Configuration data when adding a font or merging fonts
struct ImColor; // Helper functions to create a color that can be converted to either u32 or float4
struct ImGuiIO; // Main configuration and I/O between your application and ImGui
struct ImGuiOnceUponAFrame; // Simple helper for running a block of code not more than once a frame, used by IMGUI_ONCE_UPON_A_FRAME macro
struct ImGuiStorage; // Simple custom key value storage
struct ImGuiStyle; // Runtime data for styling/colors
struct ImGuiTextFilter; // Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]"
struct ImGuiTextBuffer; // Text buffer for logging/accumulating text
struct ImGuiTextEditCallbackData; // Shared state of ImGui::InputText() when using custom ImGuiTextEditCallback (rare/advanced use)
struct ImGuiSizeConstraintCallbackData;// Structure used to constraint window size in custom ways when using custom ImGuiSizeConstraintCallback (rare/advanced use)
struct ImGuiListClipper; // Helper to manually clip large list of items
struct ImGuiContext; // ImGui context (opaque)
// Enumerations (declared as int for compatibility and to not pollute the top of this file)
typedef unsigned int ImU32; typedef unsigned int ImU32;
typedef unsigned short ImWchar; // character for keyboard input/display typedef unsigned short ImWchar; // character for keyboard input/display
typedef void* ImTextureID; // user data to refer to a texture (e.g. store your texture handle/id) typedef void* ImTextureID; // user data to identify a texture (this is whatever to you want it to be! read the FAQ about ImTextureID in imgui.cpp)
typedef ImU32 ImGuiID; // unique ID used by widgets (typically hashed from a stack of string) typedef ImU32 ImGuiID; // unique ID used by widgets (typically hashed from a stack of string)
typedef int ImGuiCol; // enum ImGuiCol_ typedef int ImGuiCol; // a color identifier for styling // enum ImGuiCol_
typedef int ImGuiStyleVar; // enum ImGuiStyleVar_ typedef int ImGuiStyleVar; // a variable identifier for styling // enum ImGuiStyleVar_
typedef int ImGuiKey; // enum ImGuiKey_ typedef int ImGuiKey; // a key identifier (ImGui-side enum) // enum ImGuiKey_
typedef int ImGuiAlign; // enum ImGuiAlign_ typedef int ImGuiAlign; // alignment // enum ImGuiAlign_
typedef int ImGuiColorEditMode; // enum ImGuiColorEditMode_ typedef int ImGuiColorEditMode; // color edit mode for ColorEdit*() // enum ImGuiColorEditMode_
typedef int ImGuiMouseCursor; // enum ImGuiMouseCursor_ typedef int ImGuiMouseCursor; // a mouse cursor identifier // enum ImGuiMouseCursor_
typedef int ImGuiWindowFlags; // enum ImGuiWindowFlags_ typedef int ImGuiWindowFlags; // window flags for Begin*() // enum ImGuiWindowFlags_
typedef int ImGuiSetCond; // enum ImGuiSetCond_ typedef int ImGuiSetCond; // condition flags for Set*() // enum ImGuiSetCond_
typedef int ImGuiInputTextFlags; // enum ImGuiInputTextFlags_ typedef int ImGuiInputTextFlags; // flags for InputText*() // enum ImGuiInputTextFlags_
typedef int ImGuiSelectableFlags; // enum ImGuiSelectableFlags_ typedef int ImGuiSelectableFlags; // flags for Selectable() // enum ImGuiSelectableFlags_
struct ImGuiTextEditCallbackData; // for advanced uses of InputText() typedef int ImGuiTreeNodeFlags; // flags for TreeNode*(), Collapsing*() // enum ImGuiTreeNodeFlags_
typedef int (*ImGuiTextEditCallback)(ImGuiTextEditCallbackData *data); typedef int (*ImGuiTextEditCallback)(ImGuiTextEditCallbackData *data);
typedef void (*ImGuiSizeConstraintCallback)(ImGuiSizeConstraintCallbackData* data);
// Others helpers at bottom of the file:
// class ImVector<> // Lightweight std::vector like class.
// IMGUI_ONCE_UPON_A_FRAME // Execute a block of code once per frame only (convenient for creating UI within deep-nested code that runs multiple times)
struct ImVec2 struct ImVec2
{ {
float x, y; float x, y;
ImVec2() { x = y = 0.0f; } ImVec2() { x = y = 0.0f; }
ImVec2(float _x, float _y) { x = _x; y = _y; } ImVec2(float _x, float _y) { x = _x; y = _y; }
#ifdef IM_VEC2_CLASS_EXTRA // Define constructor and implicit cast operators in imconfig.h to convert back<>forth from your math types and ImVec2. #ifdef IM_VEC2_CLASS_EXTRA // Define constructor and implicit cast operators in imconfig.h to convert back<>forth from your math types and ImVec2.
IM_VEC2_CLASS_EXTRA IM_VEC2_CLASS_EXTRA
#endif #endif
@ -79,25 +100,11 @@ struct ImVec4
float x, y, z, w; float x, y, z, w;
ImVec4() { x = y = z = w = 0.0f; } ImVec4() { x = y = z = w = 0.0f; }
ImVec4(float _x, float _y, float _z, float _w) { x = _x; y = _y; z = _z; w = _w; } ImVec4(float _x, float _y, float _z, float _w) { x = _x; y = _y; z = _z; w = _w; }
#ifdef IM_VEC4_CLASS_EXTRA // Define constructor and implicit cast operators in imconfig.h to convert back<>forth from your math types and ImVec4. #ifdef IM_VEC4_CLASS_EXTRA // Define constructor and implicit cast operators in imconfig.h to convert back<>forth from your math types and ImVec4.
IM_VEC4_CLASS_EXTRA IM_VEC4_CLASS_EXTRA
#endif #endif
}; };
// Helpers at bottom of the file:
// - class ImVector<> // Lightweight std::vector like class.
// - IMGUI_ONCE_UPON_A_FRAME // Execute a block of code once per frame only (convenient for creating UI within deep-nested code that runs multiple times)
// - struct ImGuiTextFilter // Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]"
// - struct ImGuiTextBuffer // Text buffer for logging/accumulating text
// - struct ImGuiStorage // Custom key value storage (if you need to alter open/close states manually)
// - struct ImGuiTextEditCallbackData // Shared state of ImGui::InputText() when using custom callbacks
// - struct ImGuiListClipper // Helper to manually clip large list of items.
// - struct ImColor // Helper functions to created packed 32-bit RGBA color values
// - struct ImDrawList // Draw command list
// - struct ImFontAtlas // Bake multiple fonts into a single texture, TTF font loader, bake glyphs into bitmap
// - struct ImFont // Single font
// ImGui end-user API // ImGui end-user API
// In a namespace so that user can add extra functions in a separate file (e.g. Value() helpers for your vector or common types) // In a namespace so that user can add extra functions in a separate file (e.g. Value() helpers for your vector or common types)
namespace ImGui namespace ImGui
@ -105,19 +112,19 @@ namespace ImGui
// Main // Main
IMGUI_API ImGuiIO& GetIO(); IMGUI_API ImGuiIO& GetIO();
IMGUI_API ImGuiStyle& GetStyle(); IMGUI_API ImGuiStyle& GetStyle();
IMGUI_API ImDrawData* GetDrawData(); // same value as passed to your RenderDrawListsFn() function. valid after Render() and until the next call to NewFrame() IMGUI_API ImDrawData* GetDrawData(); // same value as passed to your io.RenderDrawListsFn() function. valid after Render() and until the next call to NewFrame()
IMGUI_API void NewFrame(); IMGUI_API void NewFrame(); // start a new ImGui frame, you can submit any command from this point until NewFrame()/Render().
IMGUI_API void Render(); IMGUI_API void Render(); // ends the ImGui frame, finalize rendering data, then call your io.RenderDrawListsFn() function if set.
IMGUI_API void Shutdown(); IMGUI_API void Shutdown();
IMGUI_API void ShowUserGuide(); // help block IMGUI_API void ShowUserGuide(); // help block
IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL); // style editor block IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL); // style editor block. you can pass in a reference ImGuiStyle structure to compare to, revert to and save to (else it uses the default style)
IMGUI_API void ShowTestWindow(bool* opened = NULL); // test window, demonstrate ImGui features IMGUI_API void ShowTestWindow(bool* p_open = NULL); // test window demonstrating ImGui features
IMGUI_API void ShowMetricsWindow(bool* opened = NULL); // metrics window for debugging imgui IMGUI_API void ShowMetricsWindow(bool* p_open = NULL); // metrics window for debugging ImGui
// Window // Window
IMGUI_API bool Begin(const char* name, bool* p_opened = NULL, ImGuiWindowFlags flags = 0); // see .cpp for details. return false when window is collapsed, so you can early out in your code. 'bool* p_opened' creates a widget on the upper-right to close the window (which sets your bool to false). IMGUI_API bool Begin(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // push window to the stack and start appending to it. see .cpp for details. return false when window is collapsed, so you can early out in your code. 'bool* p_open' creates a widget on the upper-right to close the window (which sets your bool to false).
IMGUI_API bool Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_use, float bg_alpha = -1.0f, ImGuiWindowFlags flags = 0); // this is the older/longer API. the extra parameters aren't very relevant. call SetNextWindowSize() instead if you want to set a window size. For regular windows, 'size_on_first_use' only applies to the first time EVER the window is created and probably not what you want! maybe obsolete this API eventually. IMGUI_API bool Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha = -1.0f, ImGuiWindowFlags flags = 0); // OBSOLETE. this is the older/longer API. the extra parameters aren't very relevant. call SetNextWindowSize() instead if you want to set a window size. For regular windows, 'size_on_first_use' only applies to the first time EVER the window is created and probably not what you want! might obsolete this API eventually.
IMGUI_API void End(); IMGUI_API void End(); // finish appending to current window, pop it off the window stack.
IMGUI_API bool BeginChild(const char* str_id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // begin a scrolling region. size==0.0f: use remaining window size, size<0.0f: use remaining window size minus abs(size). size>0.0f: fixed size. each axis can use a different mode, e.g. ImVec2(0,400). IMGUI_API bool BeginChild(const char* str_id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // begin a scrolling region. size==0.0f: use remaining window size, size<0.0f: use remaining window size minus abs(size). size>0.0f: fixed size. each axis can use a different mode, e.g. ImVec2(0,400).
IMGUI_API bool BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // " IMGUI_API bool BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // "
IMGUI_API void EndChild(); IMGUI_API void EndChild();
@ -128,28 +135,27 @@ namespace ImGui
IMGUI_API ImVec2 GetWindowContentRegionMax(); // content boundaries max (roughly (0,0)+Size-Scroll) where Size can be override with SetNextWindowContentSize(), 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(); // IMGUI_API float GetWindowContentRegionWidth(); //
IMGUI_API ImDrawList* GetWindowDrawList(); // get rendering command-list if you want to append your own draw primitives IMGUI_API ImDrawList* GetWindowDrawList(); // get rendering command-list if you want to append your own draw primitives
IMGUI_API ImFont* GetWindowFont();
IMGUI_API float GetWindowFontSize(); // size (also height in pixels) of current font with current scale applied
IMGUI_API void SetWindowFontScale(float scale); // per-window font scale. Adjust IO.FontGlobalScale if you want to scale all windows
IMGUI_API ImVec2 GetWindowPos(); // get current window position in screen space (useful if you want to do your own drawing via the DrawList api) IMGUI_API ImVec2 GetWindowPos(); // get current window position in screen space (useful if you want to do your own drawing via the DrawList api)
IMGUI_API ImVec2 GetWindowSize(); // get current window size IMGUI_API ImVec2 GetWindowSize(); // get current window size
IMGUI_API float GetWindowWidth(); IMGUI_API float GetWindowWidth();
IMGUI_API float GetWindowHeight(); IMGUI_API float GetWindowHeight();
IMGUI_API bool IsWindowCollapsed(); IMGUI_API bool IsWindowCollapsed();
IMGUI_API void SetWindowFontScale(float scale); // per-window font scale. Adjust IO.FontGlobalScale if you want to scale all windows
IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiSetCond cond = 0); // set next window position. call before Begin() IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiSetCond cond = 0); // set next window position. call before Begin()
IMGUI_API void SetNextWindowPosCenter(ImGuiSetCond cond = 0); // set next window position to be centered on screen. call before Begin() IMGUI_API void SetNextWindowPosCenter(ImGuiSetCond cond = 0); // set next window position to be centered on screen. call before Begin()
IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiSetCond cond = 0); // set next window size. set axis to 0.0f to force an auto-fit on this axis. call before Begin() IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiSetCond cond = 0); // set next window size. set axis to 0.0f to force an auto-fit on this axis. call before Begin()
IMGUI_API void SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeConstraintCallback custom_callback = NULL, void* custom_callback_data = NULL); // set next window size limits. use -1,-1 on either X/Y axis to preserve the current size. Use callback to apply non-trivial programmatic constraints.
IMGUI_API void SetNextWindowContentSize(const ImVec2& size); // set next window content size (enforce the range of scrollbars). set axis to 0.0f to leave it automatic. call before Begin() IMGUI_API void SetNextWindowContentSize(const ImVec2& size); // set next window content size (enforce the range of scrollbars). set axis to 0.0f to leave it automatic. call before Begin()
IMGUI_API void SetNextWindowContentWidth(float width); // set next window content width (enforce the range of horizontal scrollbar). call before Begin() IMGUI_API void SetNextWindowContentWidth(float width); // set next window content width (enforce the range of horizontal scrollbar). call before Begin()
IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiSetCond cond = 0); // set next window collapsed state. call before Begin() IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiSetCond cond = 0); // set next window collapsed state. call before Begin()
IMGUI_API void SetNextWindowFocus(); // set next window to be focused / front-most. call before Begin() IMGUI_API void SetNextWindowFocus(); // set next window to be focused / front-most. call before Begin()
IMGUI_API void SetWindowPos(const ImVec2& pos, ImGuiSetCond cond = 0); // set current window position - call within Begin()/End(). may incur tearing IMGUI_API void SetWindowPos(const ImVec2& pos, ImGuiSetCond cond = 0); // (not recommended) set current window position - call within Begin()/End(). prefer using SetNextWindowPos(), as this may incur tearing and side-effects.
IMGUI_API void SetWindowSize(const ImVec2& size, ImGuiSetCond cond = 0); // set current window size. set to ImVec2(0,0) to force an auto-fit. may incur tearing IMGUI_API void SetWindowSize(const ImVec2& size, ImGuiSetCond cond = 0); // (not recommended) set current window size - call within Begin()/End(). set to ImVec2(0,0) to force an auto-fit. prefer using SetNextWindowSize(), as this may incur tearing and minor side-effects.
IMGUI_API void SetWindowCollapsed(bool collapsed, ImGuiSetCond cond = 0); // set current window collapsed state IMGUI_API void SetWindowCollapsed(bool collapsed, ImGuiSetCond cond = 0); // (not recommended) set current window collapsed state. prefer using SetNextWindowCollapsed().
IMGUI_API void SetWindowFocus(); // set current window to be focused / front-most IMGUI_API void SetWindowFocus(); // (not recommended) set current window to be focused / front-most. prefer using SetNextWindowFocus().
IMGUI_API void SetWindowPos(const char* name, const ImVec2& pos, ImGuiSetCond cond = 0); // set named window position - call within Begin()/End(). may incur tearing IMGUI_API void SetWindowPos(const char* name, const ImVec2& pos, ImGuiSetCond cond = 0); // set named window position.
IMGUI_API void SetWindowSize(const char* name, const ImVec2& size, ImGuiSetCond cond = 0); // set named window size. set axis to 0.0f to force an auto-fit on this axis. may incur tearing IMGUI_API void SetWindowSize(const char* name, const ImVec2& size, ImGuiSetCond cond = 0); // set named window size. set axis to 0.0f to force an auto-fit on this axis.
IMGUI_API void SetWindowCollapsed(const char* name, bool collapsed, ImGuiSetCond cond = 0); // set named window collapsed state IMGUI_API void SetWindowCollapsed(const char* name, bool collapsed, ImGuiSetCond cond = 0); // set named window collapsed state
IMGUI_API void SetWindowFocus(const char* name); // set named window to be focused / front-most. use NULL to remove focus. IMGUI_API void SetWindowFocus(const char* name); // set named window to be focused / front-most. use NULL to remove focus.
@ -161,7 +167,7 @@ namespace ImGui
IMGUI_API void SetScrollY(float scroll_y); // set scrolling amount [0..GetScrollMaxY()] IMGUI_API void SetScrollY(float scroll_y); // set scrolling amount [0..GetScrollMaxY()]
IMGUI_API void SetScrollHere(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. IMGUI_API void SetScrollHere(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.
IMGUI_API void SetScrollFromPosY(float pos_y, float center_y_ratio = 0.5f); // adjust scrolling amount to make given position valid. use GetCursorPos() or GetCursorStartPos()+offset to get valid positions. IMGUI_API void SetScrollFromPosY(float pos_y, float center_y_ratio = 0.5f); // adjust scrolling amount to make given position valid. use GetCursorPos() or GetCursorStartPos()+offset to get valid positions.
IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use negative 'offset' to access previous widgets.
IMGUI_API void SetStateStorage(ImGuiStorage* tree); // replace tree state storage with our own (if you want to manipulate it yourself, typically clear subsection of it) IMGUI_API void SetStateStorage(ImGuiStorage* tree); // replace tree state storage with our own (if you want to manipulate it yourself, typically clear subsection of it)
IMGUI_API ImGuiStorage* GetStateStorage(); IMGUI_API ImGuiStorage* GetStateStorage();
@ -173,6 +179,9 @@ namespace ImGui
IMGUI_API void PushStyleVar(ImGuiStyleVar idx, float val); IMGUI_API void PushStyleVar(ImGuiStyleVar idx, float val);
IMGUI_API void PushStyleVar(ImGuiStyleVar idx, const ImVec2& val); IMGUI_API void PushStyleVar(ImGuiStyleVar idx, const ImVec2& val);
IMGUI_API void PopStyleVar(int count = 1); IMGUI_API void PopStyleVar(int count = 1);
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(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(const ImVec4& col); // retrieve given color with style alpha applied
@ -188,21 +197,15 @@ namespace ImGui
IMGUI_API void PopButtonRepeat(); IMGUI_API void PopButtonRepeat();
// Cursor / Layout // Cursor / Layout
IMGUI_API void BeginGroup(); // lock horizontal starting position. once closing a group it is seen as a single item (so you can use IsItemHovered() on a group, SameLine() between groups, etc.
IMGUI_API void EndGroup();
IMGUI_API void Separator(); // horizontal line IMGUI_API void Separator(); // horizontal line
IMGUI_API void SameLine(float local_pos_x = 0.0f, float spacing_w = -1.0f); // call between widgets or groups to layout them horizontally IMGUI_API void SameLine(float pos_x = 0.0f, float spacing_w = -1.0f); // call between widgets or groups to layout them horizontally
IMGUI_API void Spacing(); // add spacing IMGUI_API void NewLine(); // undo a SameLine()
IMGUI_API void Spacing(); // add vertical spacing
IMGUI_API void Dummy(const ImVec2& size); // add a dummy item of given size IMGUI_API void Dummy(const ImVec2& size); // add a dummy item of given size
IMGUI_API void Indent(); // move content position toward the right by style.IndentSpacing pixels IMGUI_API void Indent(float indent_w = 0.0f); // move content position toward the right, by style.IndentSpacing or indent_w if >0
IMGUI_API void Unindent(); // move content position back to the left (cancel Indent) IMGUI_API void Unindent(float indent_w = 0.0f); // move content position back to the left, by style.IndentSpacing or indent_w if >0
IMGUI_API void Columns(int count = 1, const char* id = NULL, bool border = true); // setup number of columns. use an identifier to distinguish multiple column sets. close with Columns(1). IMGUI_API void BeginGroup(); // lock horizontal starting position + capture group bounding box into one "item" (so you can use IsItemHovered() or layout primitives such as SameLine() on whole group, etc.)
IMGUI_API void NextColumn(); // next column IMGUI_API void EndGroup();
IMGUI_API int GetColumnIndex(); // get current column index
IMGUI_API float GetColumnOffset(int column_index = -1); // get position of column line (in pixels, from the left side of the contents region). pass -1 to use current column, otherwise 0..GetcolumnsCount() inclusive. column 0 is usually 0.0f and not resizable unless you call this
IMGUI_API void SetColumnOffset(int column_index, float offset_x); // set position of column line (in pixels, from the left side of the contents region). pass -1 to use current column
IMGUI_API float GetColumnWidth(int column_index = -1); // column width (== GetColumnOffset(GetColumnIndex()+1) - GetColumnOffset(GetColumnOffset())
IMGUI_API int GetColumnsCount(); // number of columns (what was passed to Columns())
IMGUI_API ImVec2 GetCursorPos(); // cursor position is relative to window position IMGUI_API ImVec2 GetCursorPos(); // cursor position is relative to window position
IMGUI_API float GetCursorPosX(); // " IMGUI_API float GetCursorPosX(); // "
IMGUI_API float GetCursorPosY(); // " IMGUI_API float GetCursorPosY(); // "
@ -210,13 +213,23 @@ namespace ImGui
IMGUI_API void SetCursorPosX(float x); // " IMGUI_API void SetCursorPosX(float x); // "
IMGUI_API void SetCursorPosY(float y); // " IMGUI_API void SetCursorPosY(float y); // "
IMGUI_API ImVec2 GetCursorStartPos(); // initial cursor position IMGUI_API ImVec2 GetCursorStartPos(); // initial cursor position
IMGUI_API ImVec2 GetCursorScreenPos(); // cursor position in absolute screen coordinates [0..io.DisplaySize] 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 void SetCursorScreenPos(const ImVec2& pos); // cursor position in absolute screen coordinates [0..io.DisplaySize]
IMGUI_API void AlignFirstTextHeightToWidgets(); // call once if the first item on the line is a Text() item and you want to vertically lower it to match subsequent (bigger) widgets IMGUI_API void AlignFirstTextHeightToWidgets(); // call once if the first item on the line is a Text() item and you want to vertically lower it to match subsequent (bigger) widgets
IMGUI_API float GetTextLineHeight(); // height of font == GetWindowFontSize() IMGUI_API float GetTextLineHeight(); // height of font == GetWindowFontSize()
IMGUI_API float GetTextLineHeightWithSpacing(); // distance (in pixels) between 2 consecutive lines of text == GetWindowFontSize() + GetStyle().ItemSpacing.y IMGUI_API float GetTextLineHeightWithSpacing(); // distance (in pixels) between 2 consecutive lines of text == GetWindowFontSize() + GetStyle().ItemSpacing.y
IMGUI_API float GetItemsLineHeightWithSpacing(); // distance (in pixels) between 2 consecutive lines of standard height widgets == GetWindowFontSize() + GetStyle().FramePadding.y*2 + GetStyle().ItemSpacing.y IMGUI_API float GetItemsLineHeightWithSpacing(); // distance (in pixels) between 2 consecutive lines of standard height widgets == GetWindowFontSize() + GetStyle().FramePadding.y*2 + GetStyle().ItemSpacing.y
// Columns
// You can also use SameLine(pos_x) for simplified columning. The columns API is still work-in-progress and rather lacking.
IMGUI_API void Columns(int count = 1, const char* id = NULL, bool border = true); // setup number of columns. use an identifier to distinguish multiple column sets. close with Columns(1).
IMGUI_API void NextColumn(); // next column
IMGUI_API int GetColumnIndex(); // get current column index
IMGUI_API float GetColumnOffset(int column_index = -1); // get position of column line (in pixels, from the left side of the contents region). pass -1 to use current column, otherwise 0..GetcolumnsCount() inclusive. column 0 is usually 0.0f and not resizable unless you call this
IMGUI_API void SetColumnOffset(int column_index, float offset_x); // set position of column line (in pixels, from the left side of the contents region). pass -1 to use current column
IMGUI_API float GetColumnWidth(int column_index = -1); // column width (== GetColumnOffset(GetColumnIndex()+1) - GetColumnOffset(GetColumnOffset())
IMGUI_API int GetColumnsCount(); // number of columns (what was passed to Columns())
// ID scopes // ID scopes
// If you are creating widgets in a loop you most likely want to push a unique identifier so ImGui can differentiate them. // If you are creating widgets in a loop you most likely want to push a unique identifier so ImGui can differentiate them.
// You can also use the "##foobar" syntax within widget label to distinguish them from each others. Read "A primer on the use of labels/IDs" in the FAQ for more details. // You can also use the "##foobar" syntax within widget label to distinguish them from each others. Read "A primer on the use of labels/IDs" in the FAQ for more details.
@ -241,15 +254,14 @@ namespace ImGui
IMGUI_API void TextUnformatted(const char* text, const char* text_end = NULL); // doesn't require null terminated string if 'text_end' is specified. no copy done to any bounded stack buffer, recommended for long chunks of text IMGUI_API void TextUnformatted(const char* text, const char* text_end = NULL); // doesn't require null terminated string if 'text_end' is specified. no copy done to any bounded stack buffer, recommended for long chunks of text
IMGUI_API void LabelText(const char* label, const char* fmt, ...) IM_PRINTFARGS(2); // display text+label aligned the same way as value+label widgets IMGUI_API void LabelText(const char* label, const char* fmt, ...) IM_PRINTFARGS(2); // display text+label aligned the same way as value+label widgets
IMGUI_API void LabelTextV(const char* label, const char* fmt, va_list args); IMGUI_API void LabelTextV(const char* label, const char* fmt, va_list args);
IMGUI_API void Bullet(); IMGUI_API void Bullet(); // draw a small circle and keep the cursor on the same line. advance cursor x position by GetTreeNodeToLabelSpacing(), same distance that TreeNode() uses
IMGUI_API void BulletText(const char* fmt, ...) IM_PRINTFARGS(1); IMGUI_API void BulletText(const char* fmt, ...) IM_PRINTFARGS(1); // shortcut for Bullet()+Text()
IMGUI_API void BulletTextV(const char* fmt, va_list args); IMGUI_API void BulletTextV(const char* fmt, va_list args);
IMGUI_API bool Button(const char* label, const ImVec2& size = ImVec2(0,0)); IMGUI_API bool Button(const char* label, const ImVec2& size = ImVec2(0,0)); // button
IMGUI_API bool SmallButton(const char* label); IMGUI_API bool SmallButton(const char* label); // button with FramePadding=(0,0)
IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size); IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size);
IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0)); IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0));
IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding
IMGUI_API bool CollapsingHeader(const char* label, const char* str_id = NULL, bool display_frame = true, bool default_open = false);
IMGUI_API bool Checkbox(const char* label, bool* v); IMGUI_API bool Checkbox(const char* label, bool* v);
IMGUI_API bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value); IMGUI_API bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value);
IMGUI_API bool RadioButton(const char* label, bool active); IMGUI_API bool RadioButton(const char* label, bool active);
@ -258,16 +270,17 @@ namespace ImGui
IMGUI_API bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int height_in_items = -1); // separate items with \0, end item-list with \0\0 IMGUI_API bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int height_in_items = -1); // separate items with \0, end item-list with \0\0
IMGUI_API bool Combo(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 Combo(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 ColorButton(const ImVec4& col, bool small_height = false, bool outline_border = true); IMGUI_API bool ColorButton(const ImVec4& col, bool small_height = false, bool outline_border = true);
IMGUI_API bool ColorEdit3(const char* label, float col[3]); IMGUI_API bool ColorEdit3(const char* label, float col[3]); // Hint: 'float col[3]' function argument is same as 'float* col'. You can pass address of first element out of a contiguous set, e.g. &myvector.x
IMGUI_API bool ColorEdit4(const char* label, float col[4], bool show_alpha = true); IMGUI_API bool ColorEdit4(const char* label, float col[4], bool show_alpha = true); // "
IMGUI_API void ColorEditMode(ImGuiColorEditMode mode); // FIXME-OBSOLETE: This is inconsistent with most of the API and should be obsoleted. IMGUI_API void ColorEditMode(ImGuiColorEditMode mode); // FIXME-OBSOLETE: This is inconsistent with most of the API and will be obsoleted/replaced.
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, 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 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)); 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));
IMGUI_API void PlotHistogram(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, 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 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(-1,0), const char* overlay = NULL);
// Widgets: Drags (tip: ctrl+click on a drag box to input text) // Widgets: Drags (tip: ctrl+click on a drag box to input with keyboard. manually input values aren't clamped, can go off-bounds)
// For all the Float2/Float3/Float4/Int2/Int3/Int4 versions of every functions, remember than a 'float v[3]' function argument is the same as 'float* v'. You can pass address of your first element out of a contiguous set, e.g. &myvector.x
IMGUI_API bool DragFloat(const char* label, float* v, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); // If v_min >= v_max we have no bound IMGUI_API bool DragFloat(const char* label, float* v, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); // If v_min >= v_max we have no bound
IMGUI_API bool DragFloat2(const char* label, float v[2], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); IMGUI_API bool DragFloat2(const char* label, float v[2], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f);
IMGUI_API bool DragFloat3(const char* label, float v[3], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); IMGUI_API bool DragFloat3(const char* label, float v[3], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f);
@ -279,7 +292,7 @@ namespace ImGui
IMGUI_API bool DragInt4(const char* label, int v[4], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); IMGUI_API bool DragInt4(const char* label, int v[4], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f");
IMGUI_API bool DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f", const char* display_format_max = NULL); IMGUI_API bool DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f", const char* display_format_max = NULL);
// Widgets: Input // Widgets: Input with Keyboard
IMGUI_API bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiTextEditCallback callback = NULL, void* user_data = NULL); IMGUI_API bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiTextEditCallback callback = NULL, void* user_data = NULL);
IMGUI_API bool InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size = ImVec2(0,0), ImGuiInputTextFlags flags = 0, ImGuiTextEditCallback callback = NULL, void* user_data = NULL); IMGUI_API bool InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size = ImVec2(0,0), ImGuiInputTextFlags flags = 0, ImGuiTextEditCallback callback = NULL, void* user_data = NULL);
IMGUI_API bool InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0); IMGUI_API bool InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0);
@ -291,7 +304,7 @@ namespace ImGui
IMGUI_API bool InputInt3(const char* label, int v[3], ImGuiInputTextFlags extra_flags = 0); IMGUI_API bool InputInt3(const char* label, int v[3], ImGuiInputTextFlags extra_flags = 0);
IMGUI_API bool InputInt4(const char* label, int v[4], ImGuiInputTextFlags extra_flags = 0); IMGUI_API bool InputInt4(const char* label, int v[4], ImGuiInputTextFlags extra_flags = 0);
// Widgets: Sliders (tip: ctrl+click on a slider to input text) // Widgets: Sliders (tip: ctrl+click on a slider to input with keyboard. manually input values aren't clamped, can go off-bounds)
IMGUI_API bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); // adjust display_format to decorate the value with a prefix or a suffix. Use power!=1.0 for logarithmic sliders IMGUI_API bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); // adjust display_format to decorate the value with a prefix or a suffix. Use power!=1.0 for logarithmic sliders
IMGUI_API bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); IMGUI_API bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
IMGUI_API bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); IMGUI_API bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
@ -305,15 +318,24 @@ namespace ImGui
IMGUI_API bool VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* display_format = "%.0f"); IMGUI_API bool VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* display_format = "%.0f");
// Widgets: Trees // Widgets: Trees
IMGUI_API bool TreeNode(const char* str_label_id); // if returning 'true' the node is open and the user is responsible for calling TreePop() IMGUI_API bool TreeNode(const char* label); // if returning 'true' the node is open and the tree id is pushed into the id stack. user is responsible for calling TreePop().
IMGUI_API bool TreeNode(const char* str_id, const char* fmt, ...) IM_PRINTFARGS(2); // " IMGUI_API bool TreeNode(const char* str_id, const char* fmt, ...) IM_PRINTFARGS(2); // read the FAQ about why and how to use ID. to align arbitrary text at the same level as a TreeNode() you can use Bullet().
IMGUI_API bool TreeNode(const void* ptr_id, const char* fmt, ...) IM_PRINTFARGS(2); // " IMGUI_API bool TreeNode(const void* ptr_id, const char* fmt, ...) IM_PRINTFARGS(2); // "
IMGUI_API bool TreeNodeV(const char* str_id, const char* fmt, va_list args); // " IMGUI_API bool TreeNodeV(const char* str_id, const char* fmt, va_list args); // "
IMGUI_API bool TreeNodeV(const void* ptr_id, const char* fmt, va_list args); // " IMGUI_API bool TreeNodeV(const void* ptr_id, const char* fmt, va_list args); // "
IMGUI_API void TreePush(const char* str_id = NULL); // already called by TreeNode(), but you can call Push/Pop yourself for layouting purpose IMGUI_API bool TreeNodeEx(const char* label, ImGuiTreeNodeFlags flags = 0);
IMGUI_API bool TreeNodeEx(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) IM_PRINTFARGS(3);
IMGUI_API bool TreeNodeEx(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) IM_PRINTFARGS(3);
IMGUI_API bool TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args);
IMGUI_API bool TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args);
IMGUI_API void TreePush(const char* str_id = NULL); // ~ Indent()+PushId(). Already called by TreeNode() when returning true, but you can call Push/Pop yourself for layout purpose
IMGUI_API void TreePush(const void* ptr_id = NULL); // " IMGUI_API void TreePush(const void* ptr_id = NULL); // "
IMGUI_API void TreePop(); IMGUI_API void TreePop(); // ~ Unindent()+PopId()
IMGUI_API void SetNextTreeNodeOpened(bool opened, ImGuiSetCond cond = 0); // set next tree node to be opened. IMGUI_API void TreeAdvanceToLabelPos(); // advance cursor x position by GetTreeNodeToLabelSpacing()
IMGUI_API float GetTreeNodeToLabelSpacing(); // horizontal distance preceeding label when using TreeNode*() or Bullet() == (g.FontSize + style.FramePadding.x*2) for a regular unframed TreeNode
IMGUI_API void SetNextTreeNodeOpen(bool is_open, ImGuiSetCond cond = 0); // set next TreeNode/CollapsingHeader open state.
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
// Widgets: Selectable / Lists // Widgets: Selectable / Lists
IMGUI_API bool Selectable(const char* label, bool selected = false, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0,0)); // size.x==0.0: use remaining width, size.x>0.0: specify width. size.y==0.0: use label height, size.y>0.0: specify height IMGUI_API bool Selectable(const char* label, bool selected = false, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0,0)); // size.x==0.0: use remaining width, size.x>0.0: specify width. size.y==0.0: use label height, size.y>0.0: specify height
@ -332,7 +354,7 @@ namespace ImGui
IMGUI_API void ValueColor(const char* prefix, const ImVec4& v); IMGUI_API void ValueColor(const char* prefix, const ImVec4& v);
IMGUI_API void ValueColor(const char* prefix, unsigned int v); IMGUI_API void ValueColor(const char* prefix, unsigned int v);
// Tooltip // Tooltips
IMGUI_API void SetTooltip(const char* fmt, ...) IM_PRINTFARGS(1); // set tooltip under mouse-cursor, typically use with ImGui::IsHovered(). last call wins IMGUI_API void SetTooltip(const char* fmt, ...) IM_PRINTFARGS(1); // set tooltip under mouse-cursor, typically use with ImGui::IsHovered(). last call wins
IMGUI_API void SetTooltipV(const char* fmt, va_list args); IMGUI_API void SetTooltipV(const char* fmt, va_list args);
IMGUI_API void BeginTooltip(); // use to create full-featured tooltip windows that aren't just text IMGUI_API void BeginTooltip(); // use to create full-featured tooltip windows that aren't just text
@ -348,17 +370,17 @@ namespace ImGui
IMGUI_API bool MenuItem(const char* label, const char* shortcut = NULL, bool selected = false, bool enabled = true); // return true when activated. shortcuts are displayed for convenience but not processed by ImGui at the moment IMGUI_API bool MenuItem(const char* label, const char* shortcut = NULL, bool selected = false, bool enabled = true); // return true when activated. shortcuts are displayed for convenience but not processed by ImGui at the moment
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 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
// Popup // Popups
IMGUI_API void OpenPopup(const char* str_id); // mark popup as open. popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). IMGUI_API void OpenPopup(const char* str_id); // mark popup as open. popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level).
IMGUI_API bool BeginPopup(const char* str_id); // return true if popup if opened and start outputting to it. only call EndPopup() if BeginPopup() returned true! IMGUI_API bool BeginPopup(const char* str_id); // return true if the popup is open, and you can start outputting to it. only call EndPopup() if BeginPopup() returned true!
IMGUI_API bool BeginPopupModal(const char* name, bool* p_opened = NULL, ImGuiWindowFlags extra_flags = 0); // modal dialog (can't close them by clicking outside) IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags extra_flags = 0); // modal dialog (can't close them by clicking outside)
IMGUI_API bool BeginPopupContextItem(const char* str_id, int mouse_button = 1); // helper to open and begin popup when clicked on last item. read comments in .cpp! IMGUI_API bool BeginPopupContextItem(const char* str_id, int mouse_button = 1); // helper to open and begin popup when clicked on last item. read comments in .cpp!
IMGUI_API bool BeginPopupContextWindow(bool also_over_items = true, const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked on current window. IMGUI_API bool BeginPopupContextWindow(bool also_over_items = true, const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked on current window.
IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked in void (no window). IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked in void (no window).
IMGUI_API void EndPopup(); IMGUI_API void EndPopup();
IMGUI_API void CloseCurrentPopup(); // close the popup we have begin-ed into. clicking on a MenuItem or Selectable automatically close the current popup. IMGUI_API void CloseCurrentPopup(); // close the popup we have begin-ed into. clicking on a MenuItem or Selectable automatically close the current popup.
// Logging: all text output from interface is redirected to tty/file/clipboard. Tree nodes are automatically opened. // Logging: all text output from interface is redirected to tty/file/clipboard. By default, tree nodes are automatically opened during logging.
IMGUI_API void LogToTTY(int max_depth = -1); // start logging to tty IMGUI_API void LogToTTY(int max_depth = -1); // start logging to tty
IMGUI_API void LogToFile(int max_depth = -1, const char* filename = NULL); // start logging to file IMGUI_API void LogToFile(int max_depth = -1, const char* filename = NULL); // start logging to file
IMGUI_API void LogToClipboard(int max_depth = -1); // start logging to OS clipboard IMGUI_API void LogToClipboard(int max_depth = -1); // start logging to OS clipboard
@ -366,20 +388,27 @@ namespace ImGui
IMGUI_API void LogButtons(); // helper to display buttons for logging to tty/file/clipboard IMGUI_API void LogButtons(); // helper to display buttons for logging to tty/file/clipboard
IMGUI_API void LogText(const char* fmt, ...) IM_PRINTFARGS(1); // pass text data straight to log (without being displayed) IMGUI_API void LogText(const char* fmt, ...) IM_PRINTFARGS(1); // pass text data straight to log (without being displayed)
// Clipping
IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect);
IMGUI_API void PopClipRect();
// Utilities // Utilities
IMGUI_API bool IsItemHovered(); // was the last item hovered by mouse? IMGUI_API bool IsItemHovered(); // was the last item hovered by mouse?
IMGUI_API bool IsItemHoveredRect(); // was the last item hovered by mouse? even if another item is active or window is blocked by popup while we are hovering this IMGUI_API bool IsItemHoveredRect(); // was the last item hovered by mouse? even if another item is active or window is blocked by popup while we are hovering this
IMGUI_API bool IsItemActive(); // was the last item active? (e.g. button being held, text field being edited- items that don't interact will always return false) IMGUI_API bool IsItemActive(); // was the last item active? (e.g. button being held, text field being edited- items that don't interact will always return false)
IMGUI_API bool IsItemClicked(int mouse_button = 0); // was the last item clicked? (e.g. button/node just clicked on)
IMGUI_API bool IsItemVisible(); // was the last item visible? (aka not out of sight due to clipping/scrolling.) IMGUI_API bool IsItemVisible(); // was the last item visible? (aka not out of sight due to clipping/scrolling.)
IMGUI_API bool IsAnyItemHovered(); IMGUI_API bool IsAnyItemHovered();
IMGUI_API bool IsAnyItemActive(); IMGUI_API bool IsAnyItemActive();
IMGUI_API ImVec2 GetItemRectMin(); // get bounding rect of last item in screen space IMGUI_API ImVec2 GetItemRectMin(); // get bounding rect of last item in screen space
IMGUI_API ImVec2 GetItemRectMax(); // " IMGUI_API ImVec2 GetItemRectMax(); // "
IMGUI_API ImVec2 GetItemRectSize(); // " IMGUI_API ImVec2 GetItemRectSize(); // "
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.
IMGUI_API bool IsWindowHovered(); // is current window hovered and hoverable (not blocked by a popup) (differentiate child windows from each others) IMGUI_API bool IsWindowHovered(); // is current window hovered and hoverable (not blocked by a popup) (differentiate child windows from each others)
IMGUI_API bool IsWindowFocused(); // is current window focused IMGUI_API bool IsWindowFocused(); // is current window focused
IMGUI_API bool IsRootWindowFocused(); // is current root window focused (top parent window in case of child windows) IMGUI_API bool IsRootWindowFocused(); // is current root window focused (root = top-most parent of a child, otherwise self)
IMGUI_API bool IsRootWindowOrAnyChildFocused(); // is current root window or any of its child (including current window) focused IMGUI_API bool IsRootWindowOrAnyChildFocused(); // is current root window or any of its child (including current window) focused
IMGUI_API bool IsRootWindowOrAnyChildHovered(); // is current root window or any of its child (including current window) hovered and hoverable (not blocked by a popup)
IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle of given size starting from cursor pos is visible (not clipped). to perform coarse clipping on user's side (as an optimization) IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle of given size starting from cursor pos is visible (not clipped). to perform coarse clipping on user's side (as an optimization)
IMGUI_API bool IsPosHoveringAnyWindow(const ImVec2& pos); // is given position hovering any active imgui window IMGUI_API bool IsPosHoveringAnyWindow(const ImVec2& pos); // is given position hovering any active imgui window
IMGUI_API float GetTime(); IMGUI_API float GetTime();
@ -408,7 +437,7 @@ namespace ImGui
IMGUI_API bool IsMouseReleased(int button); // did mouse button released (went from Down to !Down) IMGUI_API bool IsMouseReleased(int button); // did mouse button released (went from Down to !Down)
IMGUI_API bool IsMouseHoveringWindow(); // is mouse hovering current window ("window" in API names always refer to current window). disregarding of any consideration of being blocked by a popup. (unlike IsWindowHovered() this will return true even if the window is blocked because of a popup) IMGUI_API bool IsMouseHoveringWindow(); // is mouse hovering current window ("window" in API names always refer to current window). disregarding of any consideration of being blocked by a popup. (unlike IsWindowHovered() this will return true even if the window is blocked because of a popup)
IMGUI_API bool IsMouseHoveringAnyWindow(); // is mouse hovering any visible window IMGUI_API bool IsMouseHoveringAnyWindow(); // is mouse hovering any visible window
IMGUI_API bool IsMouseHoveringRect(const ImVec2& pos_min, const ImVec2& pos_max, bool clip = true); // is mouse hovering given bounding rect (in screen space). clipped by current clipping settings. disregarding of consideration of focus/window ordering/blocked by a popup. IMGUI_API bool IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip = true); // is mouse hovering given bounding rect (in screen space). clipped by current clipping settings. disregarding of consideration of focus/window ordering/blocked by a popup.
IMGUI_API bool IsMouseDragging(int button = 0, float lock_threshold = -1.0f); // is mouse dragging. if lock_threshold < -1.0f uses io.MouseDraggingThreshold IMGUI_API bool IsMouseDragging(int button = 0, float lock_threshold = -1.0f); // is mouse dragging. if lock_threshold < -1.0f uses io.MouseDraggingThreshold
IMGUI_API ImVec2 GetMousePos(); // shortcut to ImGui::GetIO().MousePos provided by user, to be consistent with other calls IMGUI_API ImVec2 GetMousePos(); // shortcut to ImGui::GetIO().MousePos provided by user, to be consistent with other calls
IMGUI_API ImVec2 GetMousePosOnOpeningCurrentPopup(); // retrieve backup of mouse positioning at the time of opening popup we have BeginPopup() into IMGUI_API ImVec2 GetMousePosOnOpeningCurrentPopup(); // retrieve backup of mouse positioning at the time of opening popup we have BeginPopup() into
@ -416,8 +445,8 @@ namespace ImGui
IMGUI_API void ResetMouseDragDelta(int button = 0); // IMGUI_API void ResetMouseDragDelta(int button = 0); //
IMGUI_API ImGuiMouseCursor GetMouseCursor(); // get desired cursor type, reset in ImGui::NewFrame(), this updated during the frame. valid before Render(). If you use software rendering by setting io.MouseDrawCursor ImGui will render those for you IMGUI_API ImGuiMouseCursor GetMouseCursor(); // get desired cursor type, reset in ImGui::NewFrame(), this updated during the frame. valid before Render(). If you use software rendering by setting io.MouseDrawCursor ImGui will render those for you
IMGUI_API void SetMouseCursor(ImGuiMouseCursor type); // set desired cursor type IMGUI_API void SetMouseCursor(ImGuiMouseCursor type); // set desired cursor type
IMGUI_API void CaptureKeyboardFromApp(); // manually enforce imgui setting the io.WantCaptureKeyboard flag next frame (your application needs to handle it). e.g. capture keyboard when your widget is being hovered. IMGUI_API void CaptureKeyboardFromApp(bool capture = true); // manually override io.WantCaptureKeyboard flag next frame (said flag is entirely left for your application handle). e.g. force capture keyboard when your widget is being hovered.
IMGUI_API void CaptureMouseFromApp(); // manually enforce imgui setting the io.WantCaptureMouse flag next frame (your application needs to handle it). IMGUI_API void CaptureMouseFromApp(bool capture = true); // manually override io.WantCaptureMouse flag next frame (said flag is entirely left for your application handle).
// Helpers functions to access functions pointers in ImGui::GetIO() // Helpers functions to access functions pointers in ImGui::GetIO()
IMGUI_API void* MemAlloc(size_t sz); IMGUI_API void* MemAlloc(size_t sz);
@ -425,15 +454,20 @@ namespace ImGui
IMGUI_API const char* GetClipboardText(); IMGUI_API const char* GetClipboardText();
IMGUI_API void SetClipboardText(const char* text); IMGUI_API void SetClipboardText(const char* text);
// Internal state/context access - if you want to use multiple ImGui context, or share context between modules (e.g. DLL), or allocate the memory yourself // Internal context access - if you want to use multiple context, share context between modules (e.g. DLL). There is a default context created and active by default.
// All contexts share a same ImFontAtlas by default. If you want different font atlas, you can new() them and overwrite the GetIO().Fonts variable of an ImGui context.
IMGUI_API const char* GetVersion(); IMGUI_API const char* GetVersion();
IMGUI_API void* GetInternalState(); IMGUI_API ImGuiContext* CreateContext(void* (*malloc_fn)(size_t) = NULL, void (*free_fn)(void*) = NULL);
IMGUI_API size_t GetInternalStateSize(); IMGUI_API void DestroyContext(ImGuiContext* ctx);
IMGUI_API void SetInternalState(void* state, bool construct = false); IMGUI_API ImGuiContext* GetCurrentContext();
IMGUI_API void SetCurrentContext(ImGuiContext* ctx);
// Obsolete (will be removed) // Obsolete (will be removed)
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
static inline void OpenNextNode(bool open) { ImGui::SetNextTreeNodeOpened(open, 0); } // OBSOLETE 1.34+ static inline bool CollapsingHeader(const char* label, const char* str_id, bool framed = true, bool default_open = false) { (void)str_id; (void)framed; ImGuiTreeNodeFlags default_open_flags = 1<<5; return CollapsingHeader(label, (default_open ? default_open_flags : 0)); } // OBSOLETE 1.49+
static inline ImFont* GetWindowFont() { return GetFont(); } // OBSOLETE 1.48+
static inline float GetWindowFontSize() { return GetFontSize(); } // OBSOLETE 1.48+
static inline void OpenNextNode(bool open) { ImGui::SetNextTreeNodeOpen(open, 0); } // OBSOLETE 1.34+
static inline bool GetWindowIsFocused() { return ImGui::IsWindowFocused(); } // OBSOLETE 1.36+ static inline bool GetWindowIsFocused() { return ImGui::IsWindowFocused(); } // OBSOLETE 1.36+
static inline bool GetWindowCollapsed() { return ImGui::IsWindowCollapsed(); } // OBSOLETE 1.39+ static inline bool GetWindowCollapsed() { return ImGui::IsWindowCollapsed(); } // OBSOLETE 1.39+
static inline ImVec2 GetItemBoxMin() { return GetItemRectMin(); } // OBSOLETE 1.36+ static inline ImVec2 GetItemBoxMin() { return GetItemRectMin(); } // OBSOLETE 1.36+
@ -453,17 +487,20 @@ enum ImGuiWindowFlags_
ImGuiWindowFlags_NoTitleBar = 1 << 0, // Disable title-bar ImGuiWindowFlags_NoTitleBar = 1 << 0, // Disable title-bar
ImGuiWindowFlags_NoResize = 1 << 1, // Disable user resizing with the lower-right grip ImGuiWindowFlags_NoResize = 1 << 1, // Disable user resizing with the lower-right grip
ImGuiWindowFlags_NoMove = 1 << 2, // Disable user moving the window ImGuiWindowFlags_NoMove = 1 << 2, // Disable user moving the window
ImGuiWindowFlags_NoScrollbar = 1 << 3, // Disable scrollbar (window can still scroll with mouse or programatically) ImGuiWindowFlags_NoScrollbar = 1 << 3, // Disable scrollbars (window can still scroll with mouse or programatically)
ImGuiWindowFlags_NoScrollWithMouse = 1 << 4, // Disable user scrolling with mouse wheel ImGuiWindowFlags_NoScrollWithMouse = 1 << 4, // Disable user vertically scrolling with mouse wheel
ImGuiWindowFlags_NoCollapse = 1 << 5, // Disable user collapsing window by double-clicking on it ImGuiWindowFlags_NoCollapse = 1 << 5, // Disable user collapsing window by double-clicking on it
ImGuiWindowFlags_AlwaysAutoResize = 1 << 6, // Resize every window to its content every frame ImGuiWindowFlags_AlwaysAutoResize = 1 << 6, // Resize every window to its content every frame
ImGuiWindowFlags_ShowBorders = 1 << 7, // Show borders around windows and items ImGuiWindowFlags_ShowBorders = 1 << 7, // Show borders around windows and items
ImGuiWindowFlags_NoSavedSettings = 1 << 8, // Never load/save settings in .ini file ImGuiWindowFlags_NoSavedSettings = 1 << 8, // Never load/save settings in .ini file
ImGuiWindowFlags_NoInputs = 1 << 9, // Disable catching mouse or keyboard inputs ImGuiWindowFlags_NoInputs = 1 << 9, // Disable catching mouse or keyboard inputs
ImGuiWindowFlags_MenuBar = 1 << 10, // Has a menu-bar ImGuiWindowFlags_MenuBar = 1 << 10, // Has a menu-bar
ImGuiWindowFlags_HorizontalScrollbar = 1 << 11, // Enable horizontal scrollbar (off by default). You need to use SetNextWindowContentSize(ImVec2(width,0.0f)); prior to calling Begin() to specify width. Read code in imgui_demo in the "Horizontal Scrolling" section. ImGuiWindowFlags_HorizontalScrollbar = 1 << 11, // Allow horizontal scrollbar to appear (off by default). You may use SetNextWindowContentSize(ImVec2(width,0.0f)); prior to calling Begin() to specify width. Read code in imgui_demo in the "Horizontal Scrolling" section.
ImGuiWindowFlags_NoFocusOnAppearing = 1 << 12, // Disable taking focus when transitioning from hidden to visible state ImGuiWindowFlags_NoFocusOnAppearing = 1 << 12, // Disable taking focus when transitioning from hidden to visible state
ImGuiWindowFlags_NoBringToFrontOnFocus = 1 << 13, // Disable bringing window to front when taking focus (e.g. clicking on it or programatically giving it focus) ImGuiWindowFlags_NoBringToFrontOnFocus = 1 << 13, // Disable bringing window to front when taking focus (e.g. clicking on it or programatically giving it focus)
ImGuiWindowFlags_AlwaysVerticalScrollbar= 1 << 14, // Always show vertical scrollbar (even if ContentSize.y < Size.y)
ImGuiWindowFlags_AlwaysHorizontalScrollbar=1<< 15, // Always show horizontal scrollbar (even if ContentSize.x < Size.x)
ImGuiWindowFlags_AlwaysUseWindowPadding = 1 << 16, // Ensure child windows without border uses style.WindowPadding (ignored by default for non-bordered child windows, because more convenient)
// [Internal] // [Internal]
ImGuiWindowFlags_ChildWindow = 1 << 20, // Don't use! For internal use by BeginChild() ImGuiWindowFlags_ChildWindow = 1 << 20, // Don't use! For internal use by BeginChild()
ImGuiWindowFlags_ChildWindowAutoFitX = 1 << 21, // Don't use! For internal use by BeginChild() ImGuiWindowFlags_ChildWindowAutoFitX = 1 << 21, // Don't use! For internal use by BeginChild()
@ -487,7 +524,7 @@ enum ImGuiInputTextFlags_
ImGuiInputTextFlags_EnterReturnsTrue = 1 << 5, // Return 'true' when Enter is pressed (as opposed to when the value was modified) ImGuiInputTextFlags_EnterReturnsTrue = 1 << 5, // Return 'true' when Enter is pressed (as opposed to when the value was modified)
ImGuiInputTextFlags_CallbackCompletion = 1 << 6, // Call user function on pressing TAB (for completion handling) ImGuiInputTextFlags_CallbackCompletion = 1 << 6, // Call user function on pressing TAB (for completion handling)
ImGuiInputTextFlags_CallbackHistory = 1 << 7, // Call user function on pressing Up/Down arrows (for history handling) ImGuiInputTextFlags_CallbackHistory = 1 << 7, // Call user function on pressing Up/Down arrows (for history handling)
ImGuiInputTextFlags_CallbackAlways = 1 << 8, // Call user function every time ImGuiInputTextFlags_CallbackAlways = 1 << 8, // Call user function every time. User code may query cursor position, modify text buffer.
ImGuiInputTextFlags_CallbackCharFilter = 1 << 9, // Call user function to filter character. Modify data->EventChar to replace/filter input, or return 1 to discard character. ImGuiInputTextFlags_CallbackCharFilter = 1 << 9, // Call user function to filter character. Modify data->EventChar to replace/filter input, or return 1 to discard character.
ImGuiInputTextFlags_AllowTabInput = 1 << 10, // Pressing TAB input a '\t' character into the text field ImGuiInputTextFlags_AllowTabInput = 1 << 10, // Pressing TAB input a '\t' character into the text field
ImGuiInputTextFlags_CtrlEnterForNewLine = 1 << 11, // In multi-line mode, allow exiting edition by pressing Enter. Ctrl+Enter to add new line (by default adds new lines with Enter). ImGuiInputTextFlags_CtrlEnterForNewLine = 1 << 11, // In multi-line mode, allow exiting edition by pressing Enter. Ctrl+Enter to add new line (by default adds new lines with Enter).
@ -499,12 +536,31 @@ enum ImGuiInputTextFlags_
ImGuiInputTextFlags_Multiline = 1 << 20 // For internal use by InputTextMultiline() ImGuiInputTextFlags_Multiline = 1 << 20 // For internal use by InputTextMultiline()
}; };
// Flags for ImGui::TreeNodeEx(), ImGui::CollapsingHeader*()
enum ImGuiTreeNodeFlags_
{
ImGuiTreeNodeFlags_Selected = 1 << 0, // Draw as selected
ImGuiTreeNodeFlags_Framed = 1 << 1, // Full colored frame (e.g. for CollapsingHeader)
ImGuiTreeNodeFlags_AllowOverlapMode = 1 << 2, // Hit testing to allow subsequent widgets to overlap this one
ImGuiTreeNodeFlags_NoTreePushOnOpen = 1 << 3, // Don't do a TreePush() when open (e.g. for CollapsingHeader) = no extra indent nor pushing on ID stack
ImGuiTreeNodeFlags_NoAutoOpenOnLog = 1 << 4, // Don't automatically and temporarily open node when Logging is active (by default logging will automatically open tree nodes)
ImGuiTreeNodeFlags_DefaultOpen = 1 << 5, // Default node to be open
ImGuiTreeNodeFlags_OpenOnDoubleClick = 1 << 6, // Need double-click to open node
ImGuiTreeNodeFlags_OpenOnArrow = 1 << 7, // Only open when clicking on the arrow part. If ImGuiTreeNodeFlags_OpenOnDoubleClick is also set, single-click arrow or double-click all box to open.
ImGuiTreeNodeFlags_Leaf = 1 << 8, // No collapsing, no arrow (use as a convenience for leaf nodes).
ImGuiTreeNodeFlags_Bullet = 1 << 9, // Display a bullet instead of arrow
//ImGuITreeNodeFlags_SpanAllAvailWidth = 1 << 10, // FIXME: TODO: Extend hit box horizontally even if not framed
//ImGuiTreeNodeFlags_NoScrollOnOpen = 1 << 11, // FIXME: TODO: Disable automatic scroll on TreePop() if node got just open and contents is not visible
ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoAutoOpenOnLog
};
// Flags for ImGui::Selectable() // Flags for ImGui::Selectable()
enum ImGuiSelectableFlags_ enum ImGuiSelectableFlags_
{ {
// Default: 0 // Default: 0
ImGuiSelectableFlags_DontClosePopups = 1 << 0, // Clicking this don't close parent popup window ImGuiSelectableFlags_DontClosePopups = 1 << 0, // Clicking this don't close parent popup window
ImGuiSelectableFlags_SpanAllColumns = 1 << 1 // Selectable frame can span all columns (text will still fit in current column) ImGuiSelectableFlags_SpanAllColumns = 1 << 1, // Selectable frame can span all columns (text will still fit in current column)
ImGuiSelectableFlags_AllowDoubleClick = 1 << 2 // Generate press events on double clicks too
}; };
// User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array // User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array
@ -537,8 +593,9 @@ enum ImGuiCol_
{ {
ImGuiCol_Text, ImGuiCol_Text,
ImGuiCol_TextDisabled, ImGuiCol_TextDisabled,
ImGuiCol_WindowBg, ImGuiCol_WindowBg, // Background of normal windows
ImGuiCol_ChildWindowBg, ImGuiCol_ChildWindowBg, // Background of child windows
ImGuiCol_PopupBg, // Background of popups, menus, tooltips windows
ImGuiCol_Border, ImGuiCol_Border,
ImGuiCol_BorderShadow, ImGuiCol_BorderShadow,
ImGuiCol_FrameBg, // Background of checkbox, radio button, plot, slider, text input ImGuiCol_FrameBg, // Background of checkbox, radio button, plot, slider, text input
@ -576,7 +633,6 @@ enum ImGuiCol_
ImGuiCol_PlotHistogram, ImGuiCol_PlotHistogram,
ImGuiCol_PlotHistogramHovered, ImGuiCol_PlotHistogramHovered,
ImGuiCol_TextSelectedBg, ImGuiCol_TextSelectedBg,
ImGuiCol_TooltipBg,
ImGuiCol_ModalWindowDarkening, // darken entire screen when a modal window is active ImGuiCol_ModalWindowDarkening, // darken entire screen when a modal window is active
ImGuiCol_COUNT ImGuiCol_COUNT
}; };
@ -609,6 +665,7 @@ enum ImGuiAlign_
}; };
// Enumeration for ColorEditMode() // Enumeration for ColorEditMode()
// FIXME-OBSOLETE: Will be replaced by future color/picker api
enum ImGuiColorEditMode_ enum ImGuiColorEditMode_
{ {
ImGuiColorEditMode_UserSelect = -2, ImGuiColorEditMode_UserSelect = -2,
@ -654,8 +711,7 @@ struct ImGuiStyle
ImVec2 ItemSpacing; // Horizontal and vertical spacing between widgets/lines ImVec2 ItemSpacing; // Horizontal and vertical spacing between widgets/lines
ImVec2 ItemInnerSpacing; // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label) ImVec2 ItemInnerSpacing; // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label)
ImVec2 TouchExtraPadding; // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! ImVec2 TouchExtraPadding; // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much!
float WindowFillAlphaDefault; // Default alpha of window background, if not specified in ImGui::Begin() float IndentSpacing; // Horizontal indentation when e.g. entering a tree node. Generally == (FontSize + FramePadding.x*2).
float IndentSpacing; // Horizontal indentation when e.g. entering a tree node
float ColumnsMinSpacing; // Minimum horizontal spacing between two columns float ColumnsMinSpacing; // Minimum horizontal spacing between two columns
float ScrollbarSize; // Width of the vertical scrollbar, Height of the horizontal scrollbar float ScrollbarSize; // Width of the vertical scrollbar, Height of the horizontal scrollbar
float ScrollbarRounding; // Radius of grab corners for scrollbar float ScrollbarRounding; // Radius of grab corners for scrollbar
@ -688,7 +744,7 @@ struct ImGuiIO
float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels. float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels.
float MouseDragThreshold; // = 6.0f // Distance threshold before considering we are dragging float MouseDragThreshold; // = 6.0f // Distance threshold before considering we are dragging
int KeyMap[ImGuiKey_COUNT]; // <unset> // Map of indices into the KeysDown[512] entries array int KeyMap[ImGuiKey_COUNT]; // <unset> // Map of indices into the KeysDown[512] entries array
float KeyRepeatDelay; // = 0.250f // When holding a key/button, time before it starts repeating, in seconds. (for actions where 'repeat' is active) float KeyRepeatDelay; // = 0.250f // When holding a key/button, time before it starts repeating, in seconds (for buttons in Repeat mode, etc.).
float KeyRepeatRate; // = 0.020f // When holding a key/button, rate at which it repeats, in seconds. float KeyRepeatRate; // = 0.020f // When holding a key/button, rate at which it repeats, in seconds.
void* UserData; // = NULL // Store your own data for retrieval by callbacks. void* UserData; // = NULL // Store your own data for retrieval by callbacks.
@ -699,6 +755,12 @@ struct ImGuiIO
ImVec2 DisplayVisibleMin; // <unset> (0.0f,0.0f) // If you use DisplaySize as a virtual space larger than your screen, set DisplayVisibleMin/Max to the visible area. ImVec2 DisplayVisibleMin; // <unset> (0.0f,0.0f) // If you use DisplaySize as a virtual space larger than your screen, set DisplayVisibleMin/Max to the visible area.
ImVec2 DisplayVisibleMax; // <unset> (0.0f,0.0f) // If the values are the same, we defaults to Min=(0.0f) and Max=DisplaySize ImVec2 DisplayVisibleMax; // <unset> (0.0f,0.0f) // If the values are the same, we defaults to Min=(0.0f) and Max=DisplaySize
// Advanced/subtle behaviors
bool WordMovementUsesAltKey; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl
bool ShortcutsUseSuperKey; // = defined(__APPLE__) // OS X style: Shortcuts using Cmd/Super instead of Ctrl
bool DoubleClickSelectsWord; // = defined(__APPLE__) // OS X style: Double click selects by word instead of selecting whole text
bool MultiSelectUsesSuperKey; // = defined(__APPLE__) // OS X style: Multi-selection in lists uses Cmd/Super instead of Ctrl [unused yet]
//------------------------------------------------------------------ //------------------------------------------------------------------
// User Functions // User Functions
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -734,13 +796,14 @@ struct ImGuiIO
bool KeyCtrl; // Keyboard modifier pressed: Control bool KeyCtrl; // Keyboard modifier pressed: Control
bool KeyShift; // Keyboard modifier pressed: Shift bool KeyShift; // Keyboard modifier pressed: Shift
bool KeyAlt; // Keyboard modifier pressed: Alt bool KeyAlt; // Keyboard modifier pressed: Alt
bool KeySuper; // Keyboard modifier pressed: Cmd/Super/Windows
bool KeysDown[512]; // Keyboard keys that are pressed (in whatever storage order you naturally have access to keyboard data) bool KeysDown[512]; // Keyboard keys that are pressed (in whatever storage order you naturally have access to keyboard data)
ImWchar InputCharacters[16+1]; // List of characters input (translated by user from keypress+keyboard state). Fill using AddInputCharacter() helper. ImWchar InputCharacters[16+1]; // List of characters input (translated by user from keypress+keyboard state). Fill using AddInputCharacter() helper.
// Functions // Functions
IMGUI_API void AddInputCharacter(ImWchar c); // Helper to add a new character into InputCharacters[] IMGUI_API void AddInputCharacter(ImWchar c); // Helper to add a new character into InputCharacters[]
IMGUI_API void AddInputCharactersUTF8(const char* utf8_chars); // Helper to add new characters into InputCharacters[] from an UTF-8 string IMGUI_API void AddInputCharactersUTF8(const char* utf8_chars); // Helper to add new characters into InputCharacters[] from an UTF-8 string
IMGUI_API void ClearInputCharacters() { InputCharacters[0] = 0; } // Helper to clear the text input buffer inline void ClearInputCharacters() { InputCharacters[0] = 0; } // Helper to clear the text input buffer
//------------------------------------------------------------------ //------------------------------------------------------------------
// Output - Retrieve after calling NewFrame(), you can use them to discard inputs or hide them from the rest of your application // Output - Retrieve after calling NewFrame(), you can use them to discard inputs or hide them from the rest of your application
@ -831,11 +894,11 @@ public:
inline void push_back(const value_type& v) { if (Size == Capacity) reserve(_grow_capacity(Size+1)); Data[Size++] = v; } inline void push_back(const value_type& v) { if (Size == Capacity) reserve(_grow_capacity(Size+1)); Data[Size++] = v; }
inline void pop_back() { IM_ASSERT(Size > 0); Size--; } inline void pop_back() { IM_ASSERT(Size > 0); Size--; }
inline iterator erase(const_iterator it) { IM_ASSERT(it >= begin() && it < end()); const ptrdiff_t off = it - begin(); memmove(Data + off, Data + off + 1, ((size_t)Size - (size_t)off - 1) * sizeof(value_type)); Size--; return Data + off; } inline iterator erase(const_iterator it) { IM_ASSERT(it >= Data && it < Data+Size); const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + 1, ((size_t)Size - (size_t)off - 1) * sizeof(value_type)); Size--; return Data + off; }
inline iterator insert(const_iterator it, const value_type& v) { IM_ASSERT(it >= begin() && it <= end()); const ptrdiff_t off = it - begin(); if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); if (off < (int)Size) memmove(Data + off + 1, Data + off, ((size_t)Size - (size_t)off) * sizeof(value_type)); Data[off] = v; Size++; return Data + off; } inline iterator insert(const_iterator it, const value_type& v) { IM_ASSERT(it >= Data && it <= Data+Size); const ptrdiff_t off = it - Data; if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); if (off < (int)Size) memmove(Data + off + 1, Data + off, ((size_t)Size - (size_t)off) * sizeof(value_type)); Data[off] = v; Size++; return Data + off; }
}; };
// Helper: execute a block of code once a frame only // Helper: execute a block of code at maximum once a frame
// Convenient if you want to quickly create an UI within deep-nested code that runs multiple times every frame. // Convenient if you want to quickly create an UI within deep-nested code that runs multiple times every frame.
// Usage: // Usage:
// IMGUI_ONCE_UPON_A_FRAME // IMGUI_ONCE_UPON_A_FRAME
@ -865,8 +928,8 @@ struct ImGuiTextFilter
const char* end() const { return e; } const char* end() const { return e; }
bool empty() const { return b == e; } bool empty() const { return b == e; }
char front() const { return *b; } char front() const { return *b; }
static bool isblank(char c) { return c == ' ' || c == '\t'; } static bool is_blank(char c) { return c == ' ' || c == '\t'; }
void trim_blanks() { while (b < e && isblank(*b)) b++; while (e > b && isblank(*(e-1))) e--; } void trim_blanks() { while (b < e && is_blank(*b)) b++; while (e > b && is_blank(*(e-1))) e--; }
IMGUI_API void split(char separator, ImVector<TextRange>& out); IMGUI_API void split(char separator, ImVector<TextRange>& out);
}; };
@ -875,6 +938,7 @@ struct ImGuiTextFilter
int CountGrep; int CountGrep;
ImGuiTextFilter(const char* default_filter = ""); ImGuiTextFilter(const char* default_filter = "");
~ImGuiTextFilter() {}
void Clear() { InputBuf[0] = 0; Build(); } void Clear() { InputBuf[0] = 0; Build(); }
bool Draw(const char* label = "Filter (inc,-exc)", float width = 0.0f); // Helper calling InputText+Build bool Draw(const char* label = "Filter (inc,-exc)", float width = 0.0f); // Helper calling InputText+Build
bool PassFilter(const char* text, const char* text_end = NULL) const; bool PassFilter(const char* text, const char* text_end = NULL) const;
@ -892,14 +956,14 @@ struct ImGuiTextBuffer
const char* begin() const { return &Buf.front(); } const char* begin() const { return &Buf.front(); }
const char* end() const { return &Buf.back(); } // Buf is zero-terminated, so end() will point on the zero-terminator const char* end() const { return &Buf.back(); } // Buf is zero-terminated, so end() will point on the zero-terminator
int size() const { return Buf.Size - 1; } int size() const { return Buf.Size - 1; }
bool empty() { return Buf.Size >= 2; } bool empty() { return Buf.Size <= 1; }
void clear() { Buf.clear(); Buf.push_back(0); } void clear() { Buf.clear(); Buf.push_back(0); }
const char* c_str() const { return Buf.Data; } const char* c_str() const { return Buf.Data; }
IMGUI_API void append(const char* fmt, ...) IM_PRINTFARGS(2); IMGUI_API void append(const char* fmt, ...) IM_PRINTFARGS(2);
IMGUI_API void appendv(const char* fmt, va_list args); IMGUI_API void appendv(const char* fmt, va_list args);
}; };
// Helper: Key->value storage // Helper: Simple Key->value storage
// - Store collapse state for a tree (Int 0/1) // - Store collapse state for a tree (Int 0/1)
// - Store color edit options (Int using values in ImGuiColorEditMode enum). // - Store color edit options (Int using values in ImGuiColorEditMode enum).
// - Custom user storage for temporary values. // - Custom user storage for temporary values.
@ -907,6 +971,7 @@ struct ImGuiTextBuffer
// Declare your own storage if: // Declare your own storage if:
// - You want to manipulate the open/close state of a particular sub-tree in your interface (tree node uses Int 0/1 to store their state). // - You want to manipulate the open/close state of a particular sub-tree in your interface (tree node uses Int 0/1 to store their state).
// - You want to store custom debug data easily without adding or editing structures in your code. // - You want to store custom debug data easily without adding or editing structures in your code.
// Types are NOT stored, so it is up to you to make sure your Key don't collide with different types.
struct ImGuiStorage struct ImGuiStorage
{ {
struct Pair struct Pair
@ -921,10 +986,12 @@ struct ImGuiStorage
// - Get***() functions find pair, never add/allocate. Pairs are sorted so a query is O(log N) // - Get***() functions find pair, never add/allocate. Pairs are sorted so a query is O(log N)
// - Set***() functions find pair, insertion on demand if missing. // - Set***() functions find pair, insertion on demand if missing.
// - Sorted insertion is costly but should amortize. A typical frame shouldn't need to insert any new pair. // - Sorted insertion is costly, paid once. A typical frame shouldn't need to insert any new pair.
IMGUI_API void Clear(); IMGUI_API void Clear();
IMGUI_API int GetInt(ImGuiID key, int default_val = 0) const; IMGUI_API int GetInt(ImGuiID key, int default_val = 0) const;
IMGUI_API void SetInt(ImGuiID key, int val); IMGUI_API void SetInt(ImGuiID key, int val);
IMGUI_API bool GetBool(ImGuiID key, bool default_val = false) const;
IMGUI_API void SetBool(ImGuiID key, bool val);
IMGUI_API float GetFloat(ImGuiID key, float default_val = 0.0f) const; IMGUI_API float GetFloat(ImGuiID key, float default_val = 0.0f) const;
IMGUI_API void SetFloat(ImGuiID key, float val); IMGUI_API void SetFloat(ImGuiID key, float val);
IMGUI_API void* GetVoidPtr(ImGuiID key) const; // default_val is NULL IMGUI_API void* GetVoidPtr(ImGuiID key) const; // default_val is NULL
@ -936,14 +1003,15 @@ struct ImGuiStorage
// float* pvar = ImGui::GetFloatRef(key); ImGui::SliderFloat("var", pvar, 0, 100.0f); some_var += *pvar; // float* pvar = ImGui::GetFloatRef(key); ImGui::SliderFloat("var", pvar, 0, 100.0f); some_var += *pvar;
// - You can also use this to quickly create temporary editable values during a session of using Edit&Continue, without restarting your application. // - You can also use this to quickly create temporary editable values during a session of using Edit&Continue, without restarting your application.
IMGUI_API int* GetIntRef(ImGuiID key, int default_val = 0); IMGUI_API int* GetIntRef(ImGuiID key, int default_val = 0);
IMGUI_API float* GetFloatRef(ImGuiID key, float default_val = 0); IMGUI_API bool* GetBoolRef(ImGuiID key, bool default_val = false);
IMGUI_API float* GetFloatRef(ImGuiID key, float default_val = 0.0f);
IMGUI_API void** GetVoidPtrRef(ImGuiID key, void* default_val = NULL); IMGUI_API void** GetVoidPtrRef(ImGuiID key, void* default_val = NULL);
// Use on your own storage if you know only integer are being stored (open/close all tree nodes) // Use on your own storage if you know only integer are being stored (open/close all tree nodes)
IMGUI_API void SetAllInt(int val); IMGUI_API void SetAllInt(int val);
}; };
// Shared state of InputText(), passed to callback when a ImGuiInputTextFlags_Callback* flag is used. // Shared state of InputText(), passed to callback when a ImGuiInputTextFlags_Callback* flag is used and the corresponding callback is triggered.
struct ImGuiTextEditCallbackData struct ImGuiTextEditCallbackData
{ {
ImGuiInputTextFlags EventFlag; // One of ImGuiInputTextFlags_Callback* // Read-only ImGuiInputTextFlags EventFlag; // One of ImGuiInputTextFlags_Callback* // Read-only
@ -955,21 +1023,35 @@ struct ImGuiTextEditCallbackData
ImWchar EventChar; // Character input // Read-write (replace character or set to zero) ImWchar EventChar; // Character input // Read-write (replace character or set to zero)
// Completion,History,Always events: // Completion,History,Always events:
// If you modify the buffer contents make sure you update 'BufTextLen' and set 'BufDirty' to true.
ImGuiKey EventKey; // Key pressed (Up/Down/TAB) // Read-only ImGuiKey EventKey; // Key pressed (Up/Down/TAB) // Read-only
char* Buf; // Current text // Read-write (pointed data only) char* Buf; // Current text buffer // Read-write (pointed data only, can't replace the actual pointer)
int BufSize; // // Read-only int BufTextLen; // Current text length in bytes // Read-write
bool BufDirty; // Must set if you modify Buf directly // Write int BufSize; // Maximum text length in bytes // Read-only
bool BufDirty; // Set if you modify Buf/BufTextLen!! // Write
int CursorPos; // // Read-write int CursorPos; // // Read-write
int SelectionStart; // // Read-write (== to SelectionEnd when no selection) int SelectionStart; // // Read-write (== to SelectionEnd when no selection)
int SelectionEnd; // // Read-write int SelectionEnd; // // Read-write
// NB: calling those function loses selection. // NB: Helper functions for text manipulation. Calling those function loses selection.
void DeleteChars(int pos, int bytes_count); void DeleteChars(int pos, int bytes_count);
void InsertChars(int pos, const char* text, const char* text_end = NULL); void InsertChars(int pos, const char* text, const char* text_end = NULL);
bool HasSelection() const { return SelectionStart != SelectionEnd; } bool HasSelection() const { return SelectionStart != SelectionEnd; }
}; };
// ImColor() is just a helper that implicity converts to either ImU32 (packed 4x1 byte) or ImVec4 (4x1 float) // Resizing callback data to apply custom constraint. As enabled by SetNextWindowSizeConstraints(). Callback is called during the next Begin().
// NB: For basic min/max size constraint on each axis you don't need to use the callback! The SetNextWindowSizeConstraints() parameters are enough.
struct ImGuiSizeConstraintCallbackData
{
void* UserData; // Read-only. What user passed to SetNextWindowSizeConstraints()
ImVec2 Pos; // Read-only. Window position, for reference.
ImVec2 CurrentSize; // Read-only. Current window size.
ImVec2 DesiredSize; // Read-write. Desired size, based on user's mouse position. Write to this field to restrain resizing.
};
// ImColor() helper to implicity converts colors to either ImU32 (packed 4x1 byte) or ImVec4 (4x1 float)
// Prefer using IM_COL32() macros if you want a guaranteed compile-time ImU32 for usage with ImDrawList API.
// Avoid storing ImColor! Store either u32 of ImVec4. This is not a full-featured color class.
// None of the ImGui API are using ImColor directly but you can use it as a convenience to pass colors in either ImU32 or ImVec4 formats. // None of the ImGui API are using ImColor directly but you can use it as a convenience to pass colors in either ImU32 or ImVec4 formats.
struct ImColor struct ImColor
{ {
@ -989,36 +1071,33 @@ struct ImColor
}; };
// Helper: Manually clip large list of items. // Helper: Manually clip large list of items.
// If you are displaying thousands of even spaced items and you have a random access to the list, you can perform clipping yourself to save on CPU. // If you are submitting lots of evenly spaced items and you have a random access to the list, you can perform coarse clipping based on visibility to save yourself from processing those items at all.
// The clipper calculates the range of visible items and advance the cursor to compensate for the non-visible items we have skipped.
// ImGui already clip items based on their bounds but it needs to measure text size to do so. Coarse clipping before submission makes this cost and your own data fetching/submission cost null.
// Usage: // Usage:
// ImGuiListClipper clipper(count, ImGui::GetTextLineHeightWithSpacing()); // ImGuiListClipper clipper(1000); // we have 1000 elements, evenly spaced.
// for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) // display only visible items // while (clipper.Step())
// for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
// ImGui::Text("line number %d", i); // ImGui::Text("line number %d", i);
// clipper.End(); // - Step 0: the clipper let you process the first element, regardless of it being visible or not, so we can measure the element height (step skipped if we passed a known height as second arg to constructor).
// NB: 'count' is only used to clamp the result, if you don't know your count you can use INT_MAX // - Step 1: the clipper infer height from first element, calculate the actual range of elements to display, and position the cursor before the first element.
// - (Step 2: dummy step only required if an explicit items_height was passed to constructor or Begin() and user call Step(). Does nothing and switch to Step 3.)
// - Step 3: the clipper validate that we have reached the expected Y position (corresponding to element DisplayEnd), advance the cursor to the end of the list and then returns 'false' to end the loop.
struct ImGuiListClipper struct ImGuiListClipper
{ {
float StartPosY;
float ItemsHeight; float ItemsHeight;
int ItemsCount, DisplayStart, DisplayEnd; int ItemsCount, StepNo, DisplayStart, DisplayEnd;
ImGuiListClipper() { ItemsHeight = 0.0f; ItemsCount = DisplayStart = DisplayEnd = -1; } // items_count: Use -1 to ignore (you can call Begin later). Use INT_MAX if you don't know how many items you have (in which case the cursor won't be advanced in the final step).
ImGuiListClipper(int count, float height) { ItemsCount = -1; Begin(count, height); } // items_height: Use -1.0f to be calculated automatically on first step. Otherwise pass in the distance between your items, typically GetTextLineHeightWithSpacing() or GetItemsLineHeightWithSpacing().
~ImGuiListClipper() { IM_ASSERT(ItemsCount == -1); } // user forgot to call End() // If you don't specify an items_height, you NEED to call Step(). If you specify items_height you may call the old Begin()/End() api directly, but prefer calling Step().
ImGuiListClipper(int items_count = -1, float items_height = -1.0f) { Begin(items_count, items_height); } // NB: Begin() initialize every fields (as we allow user to call Begin/End multiple times on a same instance if they want).
~ImGuiListClipper() { IM_ASSERT(ItemsCount == -1); } // Assert if user forgot to call End() or Step() until false.
void Begin(int count, float height) // items_height: generally pass GetTextLineHeightWithSpacing() or GetItemsLineHeightWithSpacing() IMGUI_API bool Step(); // Call until it returns false. The DisplayStart/DisplayEnd fields will be set and you can process/draw those items.
{ IMGUI_API void Begin(int items_count, float items_height = -1.0f); // Automatically called by constructor if you passed 'items_count' or by Step() in Step 1.
IM_ASSERT(ItemsCount == -1); IMGUI_API void End(); // Automatically called on the last call of Step() that returns false.
ItemsCount = count;
ItemsHeight = height;
ImGui::CalcListClipping(ItemsCount, ItemsHeight, &DisplayStart, &DisplayEnd); // calculate how many to clip/display
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + DisplayStart * ItemsHeight); // advance cursor
}
void End()
{
IM_ASSERT(ItemsCount >= 0);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (ItemsCount - DisplayEnd) * ItemsHeight); // advance cursor
ItemsCount = -1;
}
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -1026,15 +1105,16 @@ struct ImGuiListClipper
// Hold a series of drawing commands. The user provides a renderer for ImDrawData which essentially contains an array of ImDrawList. // Hold a series of drawing commands. The user provides a renderer for ImDrawData which essentially contains an array of ImDrawList.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Helpers macros to generate 32-bits encoded colors
#define IM_COL32(R,G,B,A) (((ImU32)(A)<<24) | ((ImU32)(B)<<16) | ((ImU32)(G)<<8) | ((ImU32)(R)))
#define IM_COL32_WHITE (0xFFFFFFFF)
#define IM_COL32_BLACK (0xFF000000)
#define IM_COL32_BLACK_TRANS (0x00000000) // Transparent black
// Draw callbacks for advanced uses. // Draw callbacks for advanced uses.
// NB- You most likely do NOT need to use draw callbacks just to create your own widget or customized UI rendering (you can poke into the draw list for that) // NB- You most likely do NOT need to use draw callbacks just to create your own widget or customized UI rendering (you can poke into the draw list for that)
// Draw callback are useful for example if you want to render a complex 3D scene inside a UI element. // Draw callback may be useful for example, A) Change your GPU render state, B) render a complex 3D scene inside a UI element (without an intermediate texture/render target), etc.
// The expected behavior from your rendering loop is: // The expected behavior from your rendering function is 'if (cmd.UserCallback != NULL) cmd.UserCallback(parent_list, cmd); else RenderTriangles()'
// if (cmd.UserCallback != NULL)
// cmd.UserCallback(parent_list, cmd);
// else
// RenderTriangles()
// It is up to you to decide if your rendering loop or the callback should be responsible for backup/restoring rendering state.
typedef void (*ImDrawCallback)(const ImDrawList* parent_list, const ImDrawCmd* cmd); typedef void (*ImDrawCallback)(const ImDrawList* parent_list, const ImDrawCmd* cmd);
// Typically, 1 command = 1 gpu draw call (unless command is a callback) // Typically, 1 command = 1 gpu draw call (unless command is a callback)
@ -1049,7 +1129,7 @@ struct ImDrawCmd
ImDrawCmd() { ElemCount = 0; ClipRect.x = ClipRect.y = -8192.0f; ClipRect.z = ClipRect.w = +8192.0f; TextureId = NULL; UserCallback = NULL; UserCallbackData = NULL; } ImDrawCmd() { ElemCount = 0; ClipRect.x = ClipRect.y = -8192.0f; ClipRect.z = ClipRect.w = +8192.0f; TextureId = NULL; UserCallback = NULL; UserCallbackData = NULL; }
}; };
// Vertex index (override with, e.g. '#define ImDrawIdx unsigned int' in ImConfig) // Vertex index (override with '#define ImDrawIdx unsigned int' inside in imconfig.h)
#ifndef ImDrawIdx #ifndef ImDrawIdx
typedef unsigned short ImDrawIdx; typedef unsigned short ImDrawIdx;
#endif #endif
@ -1063,9 +1143,9 @@ struct ImDrawVert
ImU32 col; ImU32 col;
}; };
#else #else
// You can change the vertex format layout by defining IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT in imconfig.h // You can override the vertex format layout by defining IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT in imconfig.h
// The code expect ImVec2 pos (8 bytes), ImVec2 uv (8 bytes), ImU32 col (4 bytes), but you can re-order them or add other fields as needed to simplify integration in your engine. // The code expect ImVec2 pos (8 bytes), ImVec2 uv (8 bytes), ImU32 col (4 bytes), but you can re-order them or add other fields as needed to simplify integration in your engine.
// The type has to be described by the #define (you can either declare the struct or use a typedef) // The type has to be described within the macro (you can either declare the struct or use a typedef)
IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT; IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT;
#endif #endif
@ -1083,7 +1163,6 @@ struct ImDrawChannel
// If you want to add custom rendering within a window, you can use ImGui::GetWindowDrawList() to access the current draw list and add your own primitives. // If you want to add custom rendering within a window, you can use ImGui::GetWindowDrawList() to access the current draw list and add your own primitives.
// You can interleave normal ImGui:: calls and adding primitives to the current draw list. // You can interleave normal ImGui:: calls and adding primitives to the current draw list.
// All positions are in screen coordinates (0,0=top-left, 1 pixel per unit). Primitives are always added to the list and not culled (culling is done at render time and at a higher-level by ImGui:: functions). // All positions are in screen coordinates (0,0=top-left, 1 pixel per unit). Primitives are always added to the list and not culled (culling is done at render time and at a higher-level by ImGui:: functions).
// Note that this only gives you access to rendering polygons. If your intent is to create custom widgets and the publicly exposed functions/data aren't sufficient, you can add code in imgui_user.inl
struct ImDrawList struct ImDrawList
{ {
// This is what you have to render // This is what you have to render
@ -1105,7 +1184,7 @@ struct ImDrawList
ImDrawList() { _OwnerName = NULL; Clear(); } ImDrawList() { _OwnerName = NULL; Clear(); }
~ImDrawList() { ClearFreeMemory(); } ~ImDrawList() { ClearFreeMemory(); }
IMGUI_API void PushClipRect(const ImVec4& clip_rect); // Scissoring. The values are x1, y1, x2, y2. Only apply to rendering. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling) IMGUI_API void PushClipRect(ImVec2 clip_rect_min, ImVec2 clip_rect_max, bool intersect_with_current_clip_rect = false); // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling)
IMGUI_API void PushClipRectFullScreen(); IMGUI_API void PushClipRectFullScreen();
IMGUI_API void PopClipRect(); IMGUI_API void PopClipRect();
IMGUI_API void PushTextureID(const ImTextureID& texture_id); IMGUI_API void PushTextureID(const ImTextureID& texture_id);
@ -1113,11 +1192,14 @@ struct ImDrawList
// Primitives // Primitives
IMGUI_API void AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness = 1.0f); IMGUI_API void AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness = 1.0f);
IMGUI_API void AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners = 0x0F); IMGUI_API void AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners = 0x0F, float thickness = 1.0f); // a: upper-left, b: lower-right
IMGUI_API void AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners = 0x0F); IMGUI_API void AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners = 0x0F); // a: upper-left, b: lower-right
IMGUI_API void AddRectFilledMultiColor(const ImVec2& a, const ImVec2& b, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left); IMGUI_API void AddRectFilledMultiColor(const ImVec2& a, const ImVec2& b, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left);
IMGUI_API void AddQuad(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col, float thickness = 1.0f);
IMGUI_API void AddQuadFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col);
IMGUI_API void AddTriangle(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col, float thickness = 1.0f);
IMGUI_API void AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col); IMGUI_API void AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col);
IMGUI_API void AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12); IMGUI_API void AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12, float thickness = 1.0f);
IMGUI_API void AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12); IMGUI_API void AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12);
IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL); IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL);
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 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);
@ -1129,7 +1211,7 @@ struct ImDrawList
// Stateful path API, add points then finish with PathFill() or PathStroke() // Stateful path API, add points then finish with PathFill() or PathStroke()
inline void PathClear() { _Path.resize(0); } inline void PathClear() { _Path.resize(0); }
inline void PathLineTo(const ImVec2& pos) { _Path.push_back(pos); } inline void PathLineTo(const ImVec2& pos) { _Path.push_back(pos); }
inline void PathLineToMergeDuplicate(const ImVec2& pos) { if (_Path.Size == 0 || _Path[_Path.Size-1].x != pos.x || _Path[_Path.Size-1].y != pos.y) _Path.push_back(pos); } inline void PathLineToMergeDuplicate(const ImVec2& pos) { if (_Path.Size == 0 || memcmp(&_Path[_Path.Size-1], &pos, 8) != 0) _Path.push_back(pos); }
inline void PathFill(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col, true); PathClear(); } inline void PathFill(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col, true); PathClear(); }
inline void PathStroke(ImU32 col, bool closed, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, closed, thickness, true); PathClear(); } inline void PathStroke(ImU32 col, bool closed, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, closed, thickness, true); PathClear(); }
IMGUI_API void PathArcTo(const ImVec2& centre, float radius, float a_min, float a_max, int num_segments = 10); IMGUI_API void PathArcTo(const ImVec2& centre, float radius, float a_min, float a_max, int num_segments = 10);
@ -1153,11 +1235,12 @@ struct ImDrawList
IMGUI_API void Clear(); IMGUI_API void Clear();
IMGUI_API void ClearFreeMemory(); IMGUI_API void ClearFreeMemory();
IMGUI_API void PrimReserve(int idx_count, int vtx_count); IMGUI_API void PrimReserve(int idx_count, int vtx_count);
IMGUI_API void PrimRect(const ImVec2& a, const ImVec2& b, ImU32 col); IMGUI_API void PrimRect(const ImVec2& a, const ImVec2& b, ImU32 col); // Axis aligned rectangle (composed of two triangles)
IMGUI_API void PrimRectUV(const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col); IMGUI_API void PrimRectUV(const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col);
inline void PrimVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) { PrimWriteIdx((ImDrawIdx)_VtxCurrentIdx); PrimWriteVtx(pos, uv, col); } IMGUI_API void PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a, const ImVec2& uv_b, const ImVec2& uv_c, const ImVec2& uv_d, ImU32 col);
inline void PrimWriteVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col){ _VtxWritePtr->pos = pos; _VtxWritePtr->uv = uv; _VtxWritePtr->col = col; _VtxWritePtr++; _VtxCurrentIdx++; } inline void PrimWriteVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col){ _VtxWritePtr->pos = pos; _VtxWritePtr->uv = uv; _VtxWritePtr->col = col; _VtxWritePtr++; _VtxCurrentIdx++; }
inline void PrimWriteIdx(ImDrawIdx idx) { *_IdxWritePtr = idx; _IdxWritePtr++; } 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); }
IMGUI_API void UpdateClipRect(); IMGUI_API void UpdateClipRect();
IMGUI_API void UpdateTextureID(); IMGUI_API void UpdateTextureID();
}; };
@ -1187,7 +1270,7 @@ struct ImFontConfig
int OversampleH, OversampleV; // 3, 1 // Rasterize at higher quality for sub-pixel positioning. We don't use sub-pixel positions on the Y axis. int OversampleH, OversampleV; // 3, 1 // Rasterize at higher quality for sub-pixel positioning. We don't use sub-pixel positions on the Y axis.
bool PixelSnapH; // false // Align every character to pixel boundary (if enabled, set OversampleH/V to 1) bool PixelSnapH; // false // Align every character to pixel boundary (if enabled, set OversampleH/V to 1)
ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs
const ImWchar* GlyphRanges; // // List of Unicode range (2 value per range, values are inclusive, zero-terminated list) const ImWchar* GlyphRanges; // // Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE.
bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese 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).
bool MergeGlyphCenterV; // false // When merging (multiple ImFontInput for one ImFont), vertically center new glyphs instead of aligning their baseline bool MergeGlyphCenterV; // false // When merging (multiple ImFontInput for one ImFont), vertically center new glyphs instead of aligning their baseline
@ -1206,6 +1289,7 @@ struct ImFontConfig
// 3. Upload the pixels data into a texture within your graphics system. // 3. Upload the pixels data into a texture within your graphics system.
// 4. Call SetTexID(my_tex_id); and pass the pointer/identifier to your texture. This value will be passed back to you during rendering to identify the texture. // 4. Call SetTexID(my_tex_id); and pass the pointer/identifier to your texture. This value will be passed back to you during rendering to identify the texture.
// 5. Call ClearTexData() to free textures memory on the heap. // 5. Call ClearTexData() to free textures memory on the heap.
// NB: If you use a 'glyph_ranges' array you need to make sure that your array persist up until the ImFont is cleared. We only copy the pointer, not the data.
struct ImFontAtlas struct ImFontAtlas
{ {
IMGUI_API ImFontAtlas(); IMGUI_API ImFontAtlas();
@ -1231,7 +1315,7 @@ struct ImFontAtlas
void SetTexID(void* id) { TexID = id; } void SetTexID(void* id) { TexID = id; }
// Helpers to retrieve list of common Unicode ranges (2 value per range, values are inclusive, zero-terminated list) // Helpers to retrieve list of common Unicode ranges (2 value per range, values are inclusive, zero-terminated list)
// (Those functions could be static but aren't so most users don't have to refer to the ImFontAtlas:: name ever if in their code; just using io.Fonts->) // NB: Make sure that your string are UTF-8 and NOT in your local code page. See FAQ for details.
IMGUI_API const ImWchar* GetGlyphRangesDefault(); // Basic Latin, Extended Latin IMGUI_API const ImWchar* GetGlyphRangesDefault(); // Basic Latin, Extended Latin
IMGUI_API const ImWchar* GetGlyphRangesKorean(); // Default + Korean characters IMGUI_API const ImWchar* GetGlyphRangesKorean(); // Default + Korean characters
IMGUI_API const ImWchar* GetGlyphRangesJapanese(); // Default + Hiragana, Katakana, Half-Width, Selection of 1946 Ideographs IMGUI_API const ImWchar* GetGlyphRangesJapanese(); // Default + Hiragana, Katakana, Half-Width, Selection of 1946 Ideographs
@ -1246,8 +1330,8 @@ struct ImFontAtlas
int TexWidth; // Texture width calculated during Build(). int TexWidth; // Texture width calculated during Build().
int TexHeight; // Texture height calculated during Build(). int TexHeight; // Texture height calculated during Build().
int TexDesiredWidth; // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height. int TexDesiredWidth; // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height.
ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel (part of the TexExtraData block) ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel
ImVector<ImFont*> Fonts; ImVector<ImFont*> Fonts; // Hold all the fonts returned by AddFont*. Fonts[0] is the default font upon calling ImGui::NewFrame(), use ImGui::PushFont()/PopFont() to change the current font.
// Private // Private
ImVector<ImFontConfig> ConfigData; // Internal data ImVector<ImFontConfig> ConfigData; // Internal data
@ -1259,15 +1343,6 @@ struct ImFontAtlas
// ImFontAtlas automatically loads a default embedded font for you when you call GetTexDataAsAlpha8() or GetTexDataAsRGBA32(). // ImFontAtlas automatically loads a default embedded font for you when you call GetTexDataAsAlpha8() or GetTexDataAsRGBA32().
struct ImFont struct ImFont
{ {
// Members: Settings
float FontSize; // <user set> // Height of characters, set during loading (don't change after loading)
float Scale; // = 1.0f // Base font scale, multiplied by the per-window font scale which you can adjust with SetFontScale()
ImVec2 DisplayOffset; // = (0.0f,1.0f) // Offset font rendering by xx pixels
ImWchar FallbackChar; // = '?' // Replacement glyph if one isn't found. Only set via SetFallbackChar()
ImFontConfig* ConfigData; // // Pointer within ImFontAtlas->ConfigData
int ConfigDataCount; //
// Members: Runtime data
struct Glyph struct Glyph
{ {
ImWchar Codepoint; ImWchar Codepoint;
@ -1275,31 +1350,50 @@ struct ImFont
float X0, Y0, X1, Y1; float X0, Y0, X1, Y1;
float U0, V0, U1, V1; // Texture coordinates float U0, V0, U1, V1; // Texture coordinates
}; };
float Ascent, Descent; // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize]
ImFontAtlas* ContainerAtlas; // What we has been loaded into // Members: Hot ~62/78 bytes
ImVector<Glyph> Glyphs; float FontSize; // <user set> // Height of characters, set during loading (don't change after loading)
float Scale; // = 1.f // Base font scale, multiplied by the per-window font scale which you can adjust with SetFontScale()
ImVec2 DisplayOffset; // = (0.f,1.f) // Offset font rendering by xx pixels
ImVector<Glyph> Glyphs; // // All glyphs.
ImVector<float> IndexXAdvance; // // Sparse. Glyphs->XAdvance in a directly indexable way (more cache-friendly, for CalcTextSize functions which are often bottleneck in large UI).
ImVector<short> IndexLookup; // // Sparse. Index glyphs by Unicode code-point.
const Glyph* FallbackGlyph; // == FindGlyph(FontFallbackChar) const Glyph* FallbackGlyph; // == FindGlyph(FontFallbackChar)
float FallbackXAdvance; // float FallbackXAdvance; // == FallbackGlyph->XAdvance
ImVector<float> IndexXAdvance; // Sparse. Glyphs->XAdvance directly indexable (more cache-friendly that reading from Glyphs, for CalcTextSize functions which are often bottleneck in large UI) ImWchar FallbackChar; // = '?' // Replacement glyph if one isn't found. Only set via SetFallbackChar()
ImVector<int> IndexLookup; // Sparse. Index glyphs by Unicode code-point.
// Members: Cold ~18/26 bytes
short ConfigDataCount; // ~ 1 // Number of ImFontConfig involved in creating this font. Bigger than 1 when merging multiple font sources into one ImFont.
ImFontConfig* ConfigData; // // Pointer within ContainerAtlas->ConfigData
ImFontAtlas* ContainerAtlas; // // What we has been loaded into
float Ascent, Descent; // // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize]
// Methods // Methods
IMGUI_API ImFont(); IMGUI_API ImFont();
IMGUI_API ~ImFont(); IMGUI_API ~ImFont();
IMGUI_API void Clear(); IMGUI_API void Clear();
IMGUI_API void BuildLookupTable(); IMGUI_API void BuildLookupTable();
IMGUI_API const Glyph* FindGlyph(unsigned short c) const; IMGUI_API const Glyph* FindGlyph(ImWchar c) const;
IMGUI_API void SetFallbackChar(ImWchar c); IMGUI_API void SetFallbackChar(ImWchar c);
float GetCharAdvance(unsigned short c) const { return ((int)c < IndexXAdvance.Size) ? IndexXAdvance[(int)c] : FallbackXAdvance; } float GetCharAdvance(ImWchar c) const { return ((int)c < IndexXAdvance.Size) ? IndexXAdvance[(int)c] : FallbackXAdvance; }
bool IsLoaded() const { return ContainerAtlas != NULL; } bool IsLoaded() const { return ContainerAtlas != NULL; }
// 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable. // 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable.
// 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable. // 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable.
IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL) const; // utf8 IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL) const; // utf8
IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const; IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const;
IMGUI_API void RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, ImDrawList* draw_list, float wrap_width = 0.0f, bool cpu_fine_clip = false) const; IMGUI_API void RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, unsigned short c) const;
IMGUI_API void RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false) const;
// Private
IMGUI_API void GrowIndex(int new_size);
IMGUI_API void AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst = true); // Makes 'dst' character/glyph points to 'src' character/glyph. Currently needs to be called AFTER fonts have been built.
}; };
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
//---- Include imgui_user.h at the end of imgui.h //---- Include imgui_user.h at the end of imgui.h
//---- So you can include code that extends ImGui using any of the types declared above. //---- So you can include code that extends ImGui using any of the types declared above.
//---- (also convenient for user to only explicitly include vanilla imgui.h) //---- (also convenient for user to only explicitly include vanilla imgui.h)

View File

@ -1,4 +1,4 @@
// dear imgui, v1.47 // dear imgui, v1.49
// (demo code) // (demo code)
// Don't remove this file from your project! It is useful reference code that you can execute. // Don't remove this file from your project! It is useful reference code that you can execute.
@ -25,13 +25,17 @@
#define snprintf _snprintf #define snprintf _snprintf
#endif #endif
#ifdef __clang__ #ifdef __clang__
#pragma clang diagnostic ignored "-Wold-style-cast" // warning : use of old-style cast // yes, they are more terse.
#pragma clang diagnostic ignored "-Wdeprecated-declarations" // warning : 'xx' is deprecated: The POSIX name for this item.. // for strdup used in demo code (so user can copy & paste the code) #pragma clang diagnostic ignored "-Wdeprecated-declarations" // warning : 'xx' is deprecated: The POSIX name for this item.. // for strdup used in demo code (so user can copy & paste the code)
#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning : cast to 'void *' from smaller integer type 'int' #pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning : cast to 'void *' from smaller integer type 'int'
#pragma clang diagnostic ignored "-Wformat-security" // warning : warning: format string is not a string literal #pragma clang diagnostic ignored "-Wformat-security" // warning : warning: format string is not a string literal
#endif #pragma clang diagnostic ignored "-Wexit-time-destructors" // warning : declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals.
#ifdef __GNUC__ #pragma clang diagnostic ignored "-Wreserved-id-macro" // warning : macro name is a reserved identifier //
#elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size #pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size
#pragma GCC diagnostic ignored "-Wformat-security" // warning : format string is not a string literal (potentially insecure) #pragma GCC diagnostic ignored "-Wformat-security" // warning : format string is not a string literal (potentially insecure)
#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function
#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value
#endif #endif
// Play it nice with Windows users. Notepad in 2015 still doesn't display text data with Unix-style \n. // Play it nice with Windows users. Notepad in 2015 still doesn't display text data with Unix-style \n.
@ -42,6 +46,7 @@
#endif #endif
#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR)/sizeof(*_ARR))) #define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR)/sizeof(*_ARR)))
#define IM_MAX(_A,_B) (((_A) >= (_B)) ? (_A) : (_B))
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// DEMO CODE // DEMO CODE
@ -49,15 +54,16 @@
#ifndef IMGUI_DISABLE_TEST_WINDOWS #ifndef IMGUI_DISABLE_TEST_WINDOWS
static void ShowExampleAppConsole(bool* opened); static void ShowExampleAppConsole(bool* p_open);
static void ShowExampleAppLog(bool* opened); static void ShowExampleAppLog(bool* p_open);
static void ShowExampleAppLayout(bool* opened); static void ShowExampleAppLayout(bool* p_open);
static void ShowExampleAppPropertyEditor(bool* opened); static void ShowExampleAppPropertyEditor(bool* p_open);
static void ShowExampleAppLongText(bool* opened); static void ShowExampleAppLongText(bool* p_open);
static void ShowExampleAppAutoResize(bool* opened); static void ShowExampleAppAutoResize(bool* p_open);
static void ShowExampleAppFixedOverlay(bool* opened); static void ShowExampleAppConstrainedResize(bool* p_open);
static void ShowExampleAppManipulatingWindowTitle(bool* opened); static void ShowExampleAppFixedOverlay(bool* p_open);
static void ShowExampleAppCustomRendering(bool* opened); static void ShowExampleAppManipulatingWindowTitle(bool* p_open);
static void ShowExampleAppCustomRendering(bool* p_open);
static void ShowExampleAppMainMenuBar(); static void ShowExampleAppMainMenuBar();
static void ShowExampleMenuFile(); static void ShowExampleMenuFile();
@ -91,7 +97,7 @@ void ImGui::ShowUserGuide()
} }
// Demonstrate most ImGui features (big function!) // Demonstrate most ImGui features (big function!)
void ImGui::ShowTestWindow(bool* p_opened) void ImGui::ShowTestWindow(bool* p_open)
{ {
// Examples apps // Examples apps
static bool show_app_main_menu_bar = false; static bool show_app_main_menu_bar = false;
@ -101,6 +107,7 @@ void ImGui::ShowTestWindow(bool* p_opened)
static bool show_app_property_editor = false; static bool show_app_property_editor = false;
static bool show_app_long_text = false; static bool show_app_long_text = false;
static bool show_app_auto_resize = false; static bool show_app_auto_resize = false;
static bool show_app_constrained_resize = false;
static bool show_app_fixed_overlay = false; static bool show_app_fixed_overlay = false;
static bool show_app_manipulating_window_title = false; static bool show_app_manipulating_window_title = false;
static bool show_app_custom_rendering = false; static bool show_app_custom_rendering = false;
@ -116,6 +123,7 @@ void ImGui::ShowTestWindow(bool* p_opened)
if (show_app_property_editor) ShowExampleAppPropertyEditor(&show_app_property_editor); if (show_app_property_editor) ShowExampleAppPropertyEditor(&show_app_property_editor);
if (show_app_long_text) ShowExampleAppLongText(&show_app_long_text); if (show_app_long_text) ShowExampleAppLongText(&show_app_long_text);
if (show_app_auto_resize) ShowExampleAppAutoResize(&show_app_auto_resize); if (show_app_auto_resize) ShowExampleAppAutoResize(&show_app_auto_resize);
if (show_app_constrained_resize) ShowExampleAppConstrainedResize(&show_app_constrained_resize);
if (show_app_fixed_overlay) ShowExampleAppFixedOverlay(&show_app_fixed_overlay); if (show_app_fixed_overlay) ShowExampleAppFixedOverlay(&show_app_fixed_overlay);
if (show_app_manipulating_window_title) ShowExampleAppManipulatingWindowTitle(&show_app_manipulating_window_title); if (show_app_manipulating_window_title) ShowExampleAppManipulatingWindowTitle(&show_app_manipulating_window_title);
if (show_app_custom_rendering) ShowExampleAppCustomRendering(&show_app_custom_rendering); if (show_app_custom_rendering) ShowExampleAppCustomRendering(&show_app_custom_rendering);
@ -139,7 +147,6 @@ void ImGui::ShowTestWindow(bool* p_opened)
static bool no_scrollbar = false; static bool no_scrollbar = false;
static bool no_collapse = false; static bool no_collapse = false;
static bool no_menu = false; static bool no_menu = false;
static float bg_alpha = -0.01f; // <0: default
// Demonstrate the various window flags. Typically you would just use the default. // Demonstrate the various window flags. Typically you would just use the default.
ImGuiWindowFlags window_flags = 0; ImGuiWindowFlags window_flags = 0;
@ -150,7 +157,8 @@ void ImGui::ShowTestWindow(bool* p_opened)
if (no_scrollbar) window_flags |= ImGuiWindowFlags_NoScrollbar; if (no_scrollbar) window_flags |= ImGuiWindowFlags_NoScrollbar;
if (no_collapse) window_flags |= ImGuiWindowFlags_NoCollapse; if (no_collapse) window_flags |= ImGuiWindowFlags_NoCollapse;
if (!no_menu) window_flags |= ImGuiWindowFlags_MenuBar; if (!no_menu) window_flags |= ImGuiWindowFlags_MenuBar;
if (!ImGui::Begin("ImGui Demo", p_opened, ImVec2(550,680), bg_alpha, window_flags)) ImGui::SetNextWindowSize(ImVec2(550,680), ImGuiSetCond_FirstUseEver);
if (!ImGui::Begin("ImGui Demo", p_open, window_flags))
{ {
// Early out if the window is collapsed, as an optimization. // Early out if the window is collapsed, as an optimization.
ImGui::End(); ImGui::End();
@ -179,6 +187,7 @@ void ImGui::ShowTestWindow(bool* p_opened)
ImGui::MenuItem("Property editor", NULL, &show_app_property_editor); ImGui::MenuItem("Property editor", NULL, &show_app_property_editor);
ImGui::MenuItem("Long text display", NULL, &show_app_long_text); ImGui::MenuItem("Long text display", NULL, &show_app_long_text);
ImGui::MenuItem("Auto-resizing window", NULL, &show_app_auto_resize); ImGui::MenuItem("Auto-resizing window", NULL, &show_app_auto_resize);
ImGui::MenuItem("Constrained-resizing window", NULL, &show_app_constrained_resize);
ImGui::MenuItem("Simple overlay", NULL, &show_app_fixed_overlay); ImGui::MenuItem("Simple overlay", NULL, &show_app_fixed_overlay);
ImGui::MenuItem("Manipulating window title", NULL, &show_app_manipulating_window_title); ImGui::MenuItem("Manipulating window title", NULL, &show_app_manipulating_window_title);
ImGui::MenuItem("Custom rendering", NULL, &show_app_custom_rendering); ImGui::MenuItem("Custom rendering", NULL, &show_app_custom_rendering);
@ -211,58 +220,12 @@ void ImGui::ShowTestWindow(bool* p_opened)
ImGui::Checkbox("No collapse", &no_collapse); ImGui::Checkbox("No collapse", &no_collapse);
ImGui::Checkbox("No menu", &no_menu); ImGui::Checkbox("No menu", &no_menu);
ImGui::PushItemWidth(100);
ImGui::DragFloat("Window Fill Alpha", &bg_alpha, 0.005f, -0.01f, 1.0f, bg_alpha < 0.0f ? "(default)" : "%.3f"); // Not exposing zero here so user doesn't "lose" the UI (zero alpha clips all widgets). But application code could have a toggle to switch between zero and non-zero.
ImGui::PopItemWidth();
if (ImGui::TreeNode("Style")) if (ImGui::TreeNode("Style"))
{ {
ImGui::ShowStyleEditor(); ImGui::ShowStyleEditor();
ImGui::TreePop(); ImGui::TreePop();
} }
if (ImGui::TreeNode("Fonts", "Fonts (%d)", ImGui::GetIO().Fonts->Fonts.Size))
{
ImGui::SameLine();
ShowHelpMarker("Tip: Load fonts with io.Fonts->AddFontFromFileTTF()\nbefore calling io.Fonts->GetTex* functions.");
ImFontAtlas* atlas = ImGui::GetIO().Fonts;
if (ImGui::TreeNode("Atlas texture", "Atlas texture (%dx%d pixels)", atlas->TexWidth, atlas->TexHeight))
{
ImGui::Image(atlas->TexID, ImVec2((float)atlas->TexWidth, (float)atlas->TexHeight), ImVec2(0,0), ImVec2(1,1), ImColor(255,255,255,255), ImColor(255,255,255,128));
ImGui::TreePop();
}
ImGui::PushItemWidth(100);
for (int i = 0; i < atlas->Fonts.Size; i++)
{
ImFont* font = atlas->Fonts[i];
ImGui::BulletText("Font %d: \'%s\', %.2f px, %d glyphs", i, font->ConfigData ? font->ConfigData[0].Name : "", font->FontSize, font->Glyphs.Size);
ImGui::TreePush((void*)(intptr_t)i);
if (i > 0) { ImGui::SameLine(); if (ImGui::SmallButton("Set as default")) { atlas->Fonts[i] = atlas->Fonts[0]; atlas->Fonts[0] = font; } }
ImGui::PushFont(font);
ImGui::Text("The quick brown fox jumps over the lazy dog");
ImGui::PopFont();
if (ImGui::TreeNode("Details"))
{
ImGui::DragFloat("font scale", &font->Scale, 0.005f, 0.3f, 2.0f, "%.1f"); // scale only this font
ImGui::Text("Ascent: %f, Descent: %f, Height: %f", font->Ascent, font->Descent, font->Ascent - font->Descent);
ImGui::Text("Fallback character: '%c' (%d)", font->FallbackChar, font->FallbackChar);
for (int config_i = 0; config_i < font->ConfigDataCount; config_i++)
{
ImFontConfig* cfg = &font->ConfigData[config_i];
ImGui::BulletText("Input %d: \'%s\'\nOversample: (%d,%d), PixelSnapH: %d", config_i, cfg->Name, cfg->OversampleH, cfg->OversampleV, cfg->PixelSnapH);
}
ImGui::TreePop();
}
ImGui::TreePop();
}
static float window_scale = 1.0f;
ImGui::DragFloat("this window scale", &window_scale, 0.005f, 0.3f, 2.0f, "%.1f"); // scale only this window
ImGui::DragFloat("global scale", &ImGui::GetIO().FontGlobalScale, 0.005f, 0.3f, 2.0f, "%.1f"); // scale everything
ImGui::PopItemWidth();
ImGui::SetWindowFontScale(window_scale);
ImGui::TreePop();
}
if (ImGui::TreeNode("Logging")) if (ImGui::TreeNode("Logging"))
{ {
ImGui::TextWrapped("The logging API redirects all text output so you can easily capture the content of a window or a block. Tree nodes can be automatically expanded. You can also call ImGui::LogText() to output directly to the log without a visual output."); ImGui::TextWrapped("The logging API redirects all text output so you can easily capture the content of a window or a block. Tree nodes can be automatically expanded. You can also call ImGui::LogText() to output directly to the log without a visual output.");
@ -273,18 +236,86 @@ void ImGui::ShowTestWindow(bool* p_opened)
if (ImGui::CollapsingHeader("Widgets")) if (ImGui::CollapsingHeader("Widgets"))
{ {
if (ImGui::TreeNode("Tree")) if (ImGui::TreeNode("Trees"))
{
if (ImGui::TreeNode("Basic trees"))
{ {
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
{
if (ImGui::TreeNode((void*)(intptr_t)i, "Child %d", i)) if (ImGui::TreeNode((void*)(intptr_t)i, "Child %d", i))
{ {
ImGui::Text("blah blah"); ImGui::Text("blah blah");
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::SmallButton("print")) if (ImGui::SmallButton("print")) printf("Child %d pressed", i);
printf("Child %d pressed", i);
ImGui::TreePop(); ImGui::TreePop();
} }
ImGui::TreePop();
}
if (ImGui::TreeNode("Advanced, with Selectable nodes"))
{
ShowHelpMarker("This is a more standard looking tree with selectable nodes.\nClick to select, CTRL+Click to toggle, click on arrows or double-click to open.");
static bool align_label_with_current_x_position = false;
ImGui::Checkbox("Align label with current X position)", &align_label_with_current_x_position);
ImGui::Text("Hello!");
if (align_label_with_current_x_position)
ImGui::Unindent(ImGui::GetTreeNodeToLabelSpacing());
static int selection_mask = (1 << 2); // Dumb representation of what may be user-side selection state. You may carry selection state inside or outside your objects in whatever format you see fit.
int node_clicked = -1; // Temporary storage of what node we have clicked to process selection at the end of the loop. May be a pointer to your own node type, etc.
ImGui::PushStyleVar(ImGuiStyleVar_IndentSpacing, ImGui::GetFontSize()*3); // Increase spacing to differentiate leaves from expanded contents.
for (int i = 0; i < 6; i++)
{
// Disable the default open on single-click behavior and pass in Selected flag according to our selection state.
ImGuiTreeNodeFlags node_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ((selection_mask & (1 << i)) ? ImGuiTreeNodeFlags_Selected : 0);
if (i < 3)
{
// Node
bool node_open = ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Node %d", i);
if (ImGui::IsItemClicked())
node_clicked = i;
if (node_open)
{
ImGui::Text("Blah blah\nBlah Blah");
ImGui::TreePop();
}
}
else
{
// Leaf: The only reason we have a TreeNode at all is to allow selection of the leaf. Otherwise we can use BulletText() or TreeAdvanceToLabelPos()+Text().
ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags | ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen, "Selectable Leaf %d", i);
if (ImGui::IsItemClicked())
node_clicked = i;
}
}
if (node_clicked != -1)
{
// Update selection state. Process outside of tree loop to avoid visual inconsistencies during the clicking-frame.
if (ImGui::GetIO().KeyCtrl)
selection_mask ^= (1 << node_clicked); // CTRL+click to toggle
else //if (!(selection_mask & (1 << node_clicked))) // Depending on selection behavior you want, this commented bit preserve selection when clicking on item that is part of the selection
selection_mask = (1 << node_clicked); // Click to single-select
}
ImGui::PopStyleVar();
if (align_label_with_current_x_position)
ImGui::Indent(ImGui::GetTreeNodeToLabelSpacing());
ImGui::TreePop();
}
ImGui::TreePop();
}
if (ImGui::TreeNode("Collapsing Headers"))
{
static bool closable_group = true;
if (ImGui::CollapsingHeader("Header"))
{
ImGui::Checkbox("Enable extra group", &closable_group);
for (int i = 0; i < 5; i++)
ImGui::Text("Some content %d", i);
}
if (ImGui::CollapsingHeader("Header with a close button", &closable_group))
{
for (int i = 0; i < 5; i++)
ImGui::Text("More content %d", i);
} }
ImGui::TreePop(); ImGui::TreePop();
} }
@ -377,14 +408,14 @@ void ImGui::ShowTestWindow(bool* p_opened)
static int pressed_count = 0; static int pressed_count = 0;
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
{ {
if (i > 0)
ImGui::SameLine();
ImGui::PushID(i); ImGui::PushID(i);
int frame_padding = -1 + i; // -1 = uses default padding int frame_padding = -1 + i; // -1 = uses default padding
if (ImGui::ImageButton(tex_id, ImVec2(32,32), ImVec2(0,0), ImVec2(32.0f/tex_w,32/tex_h), frame_padding, ImColor(0,0,0,255))) if (ImGui::ImageButton(tex_id, ImVec2(32,32), ImVec2(0,0), ImVec2(32.0f/tex_w,32/tex_h), frame_padding, ImColor(0,0,0,255)))
pressed_count += 1; pressed_count += 1;
ImGui::PopID(); ImGui::PopID();
ImGui::SameLine();
} }
ImGui::NewLine();
ImGui::Text("Pressed %d times.", pressed_count); ImGui::Text("Pressed %d times.", pressed_count);
ImGui::TreePop(); ImGui::TreePop();
} }
@ -393,11 +424,14 @@ void ImGui::ShowTestWindow(bool* p_opened)
{ {
if (ImGui::TreeNode("Basic")) if (ImGui::TreeNode("Basic"))
{ {
static bool selected[3] = { false, true, false }; static bool selected[4] = { false, true, false, false };
ImGui::Selectable("1. I am selectable", &selected[0]); ImGui::Selectable("1. I am selectable", &selected[0]);
ImGui::Selectable("2. I am selectable", &selected[1]); ImGui::Selectable("2. I am selectable", &selected[1]);
ImGui::Text("3. I am not selectable"); ImGui::Text("3. I am not selectable");
ImGui::Selectable("4. I am selectable", &selected[2]); ImGui::Selectable("4. I am selectable", &selected[2]);
if (ImGui::Selectable("5. I am double clickable", selected[3], ImGuiSelectableFlags_AllowDoubleClick))
if (ImGui::IsMouseDoubleClicked(0))
selected[3] = !selected[3];
ImGui::TreePop(); ImGui::TreePop();
} }
if (ImGui::TreeNode("Rendering more text into the same block")) if (ImGui::TreeNode("Rendering more text into the same block"))
@ -414,7 +448,7 @@ void ImGui::ShowTestWindow(bool* p_opened)
for (int i = 0; i < 16; i++) for (int i = 0; i < 16; i++)
{ {
ImGui::PushID(i); ImGui::PushID(i);
if (ImGui::Selectable("Me", &selected[i], 0, ImVec2(50,50))) if (ImGui::Selectable("Sailor", &selected[i], 0, ImVec2(50,50)))
{ {
int x = i % 4, y = i / 4; int x = i % 4, y = i / 4;
if (x > 0) selected[i - 1] ^= 1; if (x > 0) selected[i - 1] ^= 1;
@ -442,9 +476,9 @@ void ImGui::ShowTestWindow(bool* p_opened)
ImGui::Text("Password input"); ImGui::Text("Password input");
static char bufpass[64] = "password123"; static char bufpass[64] = "password123";
ImGui::InputText("password", bufpass, 64, ImGuiInputTextFlags_Password); ImGui::InputText("password", bufpass, 64, ImGuiInputTextFlags_Password | ImGuiInputTextFlags_CharsNoBlank);
ImGui::SameLine(); ShowHelpMarker("Display all characters as '*'.\nDisable clipboard cut and copy.\nDisable logging.\n"); ImGui::SameLine(); ShowHelpMarker("Display all characters as '*'.\nDisable clipboard cut and copy.\nDisable logging.\n");
ImGui::InputText("password (clear)", bufpass, 64); ImGui::InputText("password (clear)", bufpass, 64, ImGuiInputTextFlags_CharsNoBlank);
ImGui::TreePop(); ImGui::TreePop();
} }
@ -694,7 +728,7 @@ void ImGui::ShowTestWindow(bool* p_opened)
if (i > 0) ImGui::SameLine(); if (i > 0) ImGui::SameLine();
ImGui::PushID(i); ImGui::PushID(i);
ImGui::PushStyleVar(ImGuiStyleVar_GrabMinSize, 40); ImGui::PushStyleVar(ImGuiStyleVar_GrabMinSize, 40);
ImGui::VSliderFloat("##v", ImVec2(40,160), &values[i], 0.0f, 1.0f, "%.2f"); ImGui::VSliderFloat("##v", ImVec2(40,160), &values[i], 0.0f, 1.0f, "%.2f\nsec");
ImGui::PopStyleVar(); ImGui::PopStyleVar();
ImGui::PopID(); ImGui::PopID();
} }
@ -714,7 +748,9 @@ void ImGui::ShowTestWindow(bool* p_opened)
static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f }; static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f };
ImGui::PlotLines("Frame Times", arr, IM_ARRAYSIZE(arr)); ImGui::PlotLines("Frame Times", arr, IM_ARRAYSIZE(arr));
static ImVector<float> values; if (values.empty()) { values.resize(90); memset(values.Data, 0, values.Size*sizeof(float)); } // Create a dummy array of contiguous float values to plot
// Tip: If your float aren't contiguous but part of a structure, you can pass a pointer to your first float and the sizeof() of your structure in the Stride parameter.
static float values[90] = { 0 };
static int values_offset = 0; static int values_offset = 0;
if (animate) if (animate)
{ {
@ -723,11 +759,11 @@ void ImGui::ShowTestWindow(bool* p_opened)
{ {
static float phase = 0.0f; static float phase = 0.0f;
values[values_offset] = cosf(phase); values[values_offset] = cosf(phase);
values_offset = (values_offset+1)%values.Size; values_offset = (values_offset+1) % IM_ARRAYSIZE(values);
phase += 0.10f*values_offset; phase += 0.10f*values_offset;
} }
} }
ImGui::PlotLines("Lines", values.Data, values.Size, values_offset, "avg 0.0", -1.0f, 1.0f, ImVec2(0,80)); ImGui::PlotLines("Lines", values, IM_ARRAYSIZE(values), values_offset, "avg 0.0", -1.0f, 1.0f, ImVec2(0,80));
ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0,80)); ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0,80));
// Use functions to generate output // Use functions to generate output
@ -813,25 +849,35 @@ void ImGui::ShowTestWindow(bool* p_opened)
{ {
static float f = 0.0f; static float f = 0.0f;
ImGui::Text("PushItemWidth(100)"); ImGui::Text("PushItemWidth(100)");
ImGui::SameLine(); ShowHelpMarker("Fixed width.");
ImGui::PushItemWidth(100); ImGui::PushItemWidth(100);
ImGui::DragFloat("float##1", &f); ImGui::DragFloat("float##1", &f);
ImGui::PopItemWidth(); ImGui::PopItemWidth();
ImGui::Text("PushItemWidth(GetWindowWidth() * 0.5f);"); ImGui::Text("PushItemWidth(GetWindowWidth() * 0.5f)");
ImGui::SameLine(); ShowHelpMarker("Half of window width.");
ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.5f); ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.5f);
ImGui::DragFloat("float##2", &f); ImGui::DragFloat("float##2", &f);
ImGui::PopItemWidth(); ImGui::PopItemWidth();
ImGui::Text("PushItemWidth(GetContentRegionAvailWidth() * 0.5f);"); ImGui::Text("PushItemWidth(GetContentRegionAvailWidth() * 0.5f)");
ImGui::SameLine(); ShowHelpMarker("Half of available width.\n(~ right-cursor_pos)\n(works within a column set)");
ImGui::PushItemWidth(ImGui::GetContentRegionAvailWidth() * 0.5f); ImGui::PushItemWidth(ImGui::GetContentRegionAvailWidth() * 0.5f);
ImGui::DragFloat("float##3", &f); ImGui::DragFloat("float##3", &f);
ImGui::PopItemWidth(); ImGui::PopItemWidth();
ImGui::Text("PushItemWidth(-100);"); ImGui::Text("PushItemWidth(-100)");
ImGui::SameLine(); ShowHelpMarker("Align to right edge minus 100");
ImGui::PushItemWidth(-100); ImGui::PushItemWidth(-100);
ImGui::DragFloat("float##4", &f); ImGui::DragFloat("float##4", &f);
ImGui::PopItemWidth(); ImGui::PopItemWidth();
ImGui::Text("PushItemWidth(-1)");
ImGui::SameLine(); ShowHelpMarker("Align to right edge");
ImGui::PushItemWidth(-1);
ImGui::DragFloat("float##5", &f);
ImGui::PopItemWidth();
ImGui::TreePop(); ImGui::TreePop();
} }
@ -987,9 +1033,9 @@ void ImGui::ShowTestWindow(bool* p_opened)
if (ImGui::TreeNode("Node##1")) { for (int i = 0; i < 6; i++) ImGui::BulletText("Item %d..", i); ImGui::TreePop(); } // Dummy tree data if (ImGui::TreeNode("Node##1")) { for (int i = 0; i < 6; i++) ImGui::BulletText("Item %d..", i); ImGui::TreePop(); } // Dummy tree data
ImGui::AlignFirstTextHeightToWidgets(); // Vertically align text node a bit lower so it'll be vertically centered with upcoming widget. Otherwise you can use SmallButton (smaller fit). ImGui::AlignFirstTextHeightToWidgets(); // Vertically align text node a bit lower so it'll be vertically centered with upcoming widget. Otherwise you can use SmallButton (smaller fit).
bool tree_opened = ImGui::TreeNode("Node##2"); // Common mistake to avoid: if we want to SameLine after TreeNode we need to do it before we add child content. bool node_open = ImGui::TreeNode("Node##2"); // Common mistake to avoid: if we want to SameLine after TreeNode we need to do it before we add child content.
ImGui::SameLine(0.0f, spacing); ImGui::Button("Button##2"); ImGui::SameLine(0.0f, spacing); ImGui::Button("Button##2");
if (tree_opened) { for (int i = 0; i < 6; i++) ImGui::BulletText("Item %d..", i); ImGui::TreePop(); } // Dummy tree data if (node_open) { for (int i = 0; i < 6; i++) ImGui::BulletText("Item %d..", i); ImGui::TreePop(); } // Dummy tree data
// Bullet // Bullet
ImGui::Button("Button##3"); ImGui::Button("Button##3");
@ -1009,9 +1055,11 @@ void ImGui::ShowTestWindow(bool* p_opened)
static bool track = true; static bool track = true;
static int track_line = 50, scroll_to_px = 200; static int track_line = 50, scroll_to_px = 200;
ImGui::Checkbox("Track", &track); ImGui::Checkbox("Track", &track);
ImGui::PushItemWidth(100);
ImGui::SameLine(130); track |= ImGui::DragInt("##line", &track_line, 0.25f, 0, 99, "Line %.0f"); ImGui::SameLine(130); track |= ImGui::DragInt("##line", &track_line, 0.25f, 0, 99, "Line %.0f");
bool scroll_to = ImGui::Button("Scroll To"); bool scroll_to = ImGui::Button("Scroll To");
ImGui::SameLine(130); scroll_to |= ImGui::DragInt("##pos_y", &scroll_to_px, 1.00f, 0, 9999, "y = %.0f px"); ImGui::SameLine(130); scroll_to |= ImGui::DragInt("##pos_y", &scroll_to_px, 1.00f, 0, 9999, "y = %.0f px");
ImGui::PopItemWidth();
if (scroll_to) track = false; if (scroll_to) track = false;
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
@ -1094,7 +1142,7 @@ void ImGui::ShowTestWindow(bool* p_opened)
ImGui::InvisibleButton("##dummy", size); ImGui::InvisibleButton("##dummy", size);
if (ImGui::IsItemActive() && ImGui::IsMouseDragging()) { offset.x += ImGui::GetIO().MouseDelta.x; offset.y += ImGui::GetIO().MouseDelta.y; } if (ImGui::IsItemActive() && ImGui::IsMouseDragging()) { offset.x += ImGui::GetIO().MouseDelta.x; offset.y += ImGui::GetIO().MouseDelta.y; }
ImGui::GetWindowDrawList()->AddRectFilled(pos, ImVec2(pos.x+size.x,pos.y+size.y), ImColor(90,90,120,255)); ImGui::GetWindowDrawList()->AddRectFilled(pos, ImVec2(pos.x+size.x,pos.y+size.y), ImColor(90,90,120,255));
ImGui::GetWindowDrawList()->AddText(ImGui::GetWindowFont(), ImGui::GetWindowFontSize()*2.0f, ImVec2(pos.x+offset.x,pos.y+offset.y), ImColor(255,255,255,255), "Line 1 hello\nLine 2 clip me!", NULL, 0.0f, &clip_rect); ImGui::GetWindowDrawList()->AddText(ImGui::GetFont(), ImGui::GetFontSize()*2.0f, ImVec2(pos.x+offset.x,pos.y+offset.y), ImColor(255,255,255,255), "Line 1 hello\nLine 2 clip me!", NULL, 0.0f, &clip_rect);
ImGui::TreePop(); ImGui::TreePop();
} }
} }
@ -1194,7 +1242,7 @@ void ImGui::ShowTestWindow(bool* p_opened)
ImGui::EndPopup(); ImGui::EndPopup();
} }
static ImVec4 color = ImColor(1.0f, 0.0f, 1.0f, 1.0f); static ImVec4 color = ImColor(0.8f, 0.5f, 1.0f, 1.0f);
ImGui::ColorButton(color); ImGui::ColorButton(color);
if (ImGui::BeginPopupContextItem("color context menu")) if (ImGui::BeginPopupContextItem("color context menu"))
{ {
@ -1220,6 +1268,9 @@ void ImGui::ShowTestWindow(bool* p_opened)
ImGui::Text("All those beautiful files will be deleted.\nThis operation cannot be undone!\n\n"); ImGui::Text("All those beautiful files will be deleted.\nThis operation cannot be undone!\n\n");
ImGui::Separator(); ImGui::Separator();
//static int dummy_i = 0;
//ImGui::Combo("Combo", &dummy_i, "Delete\0Delete harder\0");
static bool dont_ask_me_next_time = false; static bool dont_ask_me_next_time = false;
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0,0)); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0,0));
ImGui::Checkbox("Don't ask me next time", &dont_ask_me_next_time); ImGui::Checkbox("Don't ask me next time", &dont_ask_me_next_time);
@ -1378,9 +1429,9 @@ void ImGui::ShowTestWindow(bool* p_opened)
ImGui::TreePop(); ImGui::TreePop();
} }
bool node_opened = ImGui::TreeNode("Tree within single cell"); bool node_open = ImGui::TreeNode("Tree within single cell");
ImGui::SameLine(); ShowHelpMarker("NB: Tree node must be poped before ending the cell.\nThere's no storage of state per-cell."); ImGui::SameLine(); ShowHelpMarker("NB: Tree node must be poped before ending the cell.\nThere's no storage of state per-cell.");
if (node_opened) if (node_open)
{ {
ImGui::Columns(2, "tree items"); ImGui::Columns(2, "tree items");
ImGui::Separator(); ImGui::Separator();
@ -1486,15 +1537,19 @@ void ImGui::ShowTestWindow(bool* p_opened)
ImGui::Text("Keys down:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (io.KeysDownDuration[i] >= 0.0f) { ImGui::SameLine(); ImGui::Text("%d (%.02f secs)", i, io.KeysDownDuration[i]); } ImGui::Text("Keys down:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (io.KeysDownDuration[i] >= 0.0f) { ImGui::SameLine(); ImGui::Text("%d (%.02f secs)", i, io.KeysDownDuration[i]); }
ImGui::Text("Keys pressed:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (ImGui::IsKeyPressed(i)) { ImGui::SameLine(); ImGui::Text("%d", i); } ImGui::Text("Keys pressed:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (ImGui::IsKeyPressed(i)) { ImGui::SameLine(); ImGui::Text("%d", i); }
ImGui::Text("Keys release:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (ImGui::IsKeyReleased(i)) { ImGui::SameLine(); ImGui::Text("%d", i); } ImGui::Text("Keys release:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (ImGui::IsKeyReleased(i)) { ImGui::SameLine(); ImGui::Text("%d", i); }
ImGui::Text("KeyMods: %s%s%s", io.KeyCtrl ? "CTRL " : "", io.KeyShift ? "SHIFT " : "", io.KeyAlt ? "ALT " : ""); ImGui::Text("KeyMods: %s%s%s%s", io.KeyCtrl ? "CTRL " : "", io.KeyShift ? "SHIFT " : "", io.KeyAlt ? "ALT " : "", io.KeySuper ? "SUPER " : "");
ImGui::Text("WantCaptureMouse: %s", io.WantCaptureMouse ? "true" : "false"); ImGui::Text("WantCaptureMouse: %s", io.WantCaptureMouse ? "true" : "false");
ImGui::Text("WantCaptureKeyboard: %s", io.WantCaptureKeyboard ? "true" : "false"); ImGui::Text("WantCaptureKeyboard: %s", io.WantCaptureKeyboard ? "true" : "false");
ImGui::Text("WantTextInput: %s", io.WantTextInput ? "true" : "false"); ImGui::Text("WantTextInput: %s", io.WantTextInput ? "true" : "false");
ImGui::Button("Hover me\nto enforce\ninputs capture"); ImGui::Button("Hovering me sets the\nkeyboard capture flag");
if (ImGui::IsItemHovered()) if (ImGui::IsItemHovered())
ImGui::CaptureKeyboardFromApp(); ImGui::CaptureKeyboardFromApp(true);
ImGui::SameLine();
ImGui::Button("Holding me clears the\nthe keyboard capture flag");
if (ImGui::IsItemActive())
ImGui::CaptureKeyboardFromApp(false);
ImGui::TreePop(); ImGui::TreePop();
} }
@ -1523,9 +1578,11 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
{ {
ImGuiStyle& style = ImGui::GetStyle(); ImGuiStyle& style = ImGui::GetStyle();
const ImGuiStyle def; // Default style // You can pass in a reference ImGuiStyle structure to compare to, revert to and save to (else it compares to the default style)
const ImGuiStyle default_style; // Default style
if (ImGui::Button("Revert Style")) if (ImGui::Button("Revert Style"))
style = ref ? *ref : def; style = ref ? *ref : default_style;
if (ref) if (ref)
{ {
ImGui::SameLine(); ImGui::SameLine();
@ -1543,7 +1600,6 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, FLT_MAX, NULL, 2.0f); ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, FLT_MAX, NULL, 2.0f);
if (style.CurveTessellationTol < 0.0f) style.CurveTessellationTol = 0.10f; if (style.CurveTessellationTol < 0.0f) style.CurveTessellationTol = 0.10f;
ImGui::DragFloat("Global Alpha", &style.Alpha, 0.005f, 0.20f, 1.0f, "%.2f"); // Not exposing zero here so user doesn't "lose" the UI (zero alpha clips all widgets). But application code could have a toggle to switch between zero and non-zero. ImGui::DragFloat("Global Alpha", &style.Alpha, 0.005f, 0.20f, 1.0f, "%.2f"); // Not exposing zero here so user doesn't "lose" the UI (zero alpha clips all widgets). But application code could have a toggle to switch between zero and non-zero.
ImGui::DragFloat("Window Fill Alpha Default", &style.WindowFillAlphaDefault, 0.005f, 0.0f, 1.0f, "%.2f");
ImGui::PopItemWidth(); ImGui::PopItemWidth();
ImGui::TreePop(); ImGui::TreePop();
} }
@ -1581,7 +1637,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
{ {
const ImVec4& col = style.Colors[i]; const ImVec4& col = style.Colors[i];
const char* name = ImGui::GetStyleColName(i); const char* name = ImGui::GetStyleColName(i);
if (!output_only_modified || memcmp(&col, (ref ? &ref->Colors[i] : &def.Colors[i]), sizeof(ImVec4)) != 0) if (!output_only_modified || memcmp(&col, (ref ? &ref->Colors[i] : &default_style.Colors[i]), sizeof(ImVec4)) != 0)
ImGui::LogText("style.Colors[ImGuiCol_%s]%*s= ImVec4(%.2ff, %.2ff, %.2ff, %.2ff);" IM_NEWLINE, name, 22 - (int)strlen(name), "", col.x, col.y, col.z, col.w); ImGui::LogText("style.Colors[ImGuiCol_%s]%*s= ImVec4(%.2ff, %.2ff, %.2ff, %.2ff);" IM_NEWLINE, name, 22 - (int)strlen(name), "", col.x, col.y, col.z, col.w);
} }
ImGui::LogFinish(); ImGui::LogFinish();
@ -1600,7 +1656,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
static ImGuiTextFilter filter; static ImGuiTextFilter filter;
filter.Draw("Filter colors", 200); filter.Draw("Filter colors", 200);
ImGui::BeginChild("#colors", ImVec2(0, 300), true); ImGui::BeginChild("#colors", ImVec2(0, 300), true, ImGuiWindowFlags_AlwaysVerticalScrollbar);
ImGui::PushItemWidth(-160); ImGui::PushItemWidth(-160);
ImGui::ColorEditMode(edit_mode); ImGui::ColorEditMode(edit_mode);
for (int i = 0; i < ImGuiCol_COUNT; i++) for (int i = 0; i < ImGuiCol_COUNT; i++)
@ -1610,9 +1666,9 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
continue; continue;
ImGui::PushID(i); ImGui::PushID(i);
ImGui::ColorEdit4(name, (float*)&style.Colors[i], true); ImGui::ColorEdit4(name, (float*)&style.Colors[i], true);
if (memcmp(&style.Colors[i], (ref ? &ref->Colors[i] : &def.Colors[i]), sizeof(ImVec4)) != 0) if (memcmp(&style.Colors[i], (ref ? &ref->Colors[i] : &default_style.Colors[i]), sizeof(ImVec4)) != 0)
{ {
ImGui::SameLine(); if (ImGui::Button("Revert")) style.Colors[i] = ref ? ref->Colors[i] : def.Colors[i]; ImGui::SameLine(); if (ImGui::Button("Revert")) style.Colors[i] = ref ? ref->Colors[i] : default_style.Colors[i];
if (ref) { ImGui::SameLine(); if (ImGui::Button("Save")) ref->Colors[i] = style.Colors[i]; } if (ref) { ImGui::SameLine(); if (ImGui::Button("Save")) ref->Colors[i] = style.Colors[i]; }
} }
ImGui::PopID(); ImGui::PopID();
@ -1623,6 +1679,47 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
ImGui::TreePop(); ImGui::TreePop();
} }
if (ImGui::TreeNode("Fonts", "Fonts (%d)", ImGui::GetIO().Fonts->Fonts.Size))
{
ImGui::SameLine(); ShowHelpMarker("Tip: Load fonts with io.Fonts->AddFontFromFileTTF()\nbefore calling io.Fonts->GetTex* functions.");
ImFontAtlas* atlas = ImGui::GetIO().Fonts;
if (ImGui::TreeNode("Atlas texture", "Atlas texture (%dx%d pixels)", atlas->TexWidth, atlas->TexHeight))
{
ImGui::Image(atlas->TexID, ImVec2((float)atlas->TexWidth, (float)atlas->TexHeight), ImVec2(0,0), ImVec2(1,1), ImColor(255,255,255,255), ImColor(255,255,255,128));
ImGui::TreePop();
}
ImGui::PushItemWidth(100);
for (int i = 0; i < atlas->Fonts.Size; i++)
{
ImFont* font = atlas->Fonts[i];
ImGui::BulletText("Font %d: \'%s\', %.2f px, %d glyphs", i, font->ConfigData ? font->ConfigData[0].Name : "", font->FontSize, font->Glyphs.Size);
ImGui::TreePush((void*)(intptr_t)i);
if (i > 0) { ImGui::SameLine(); if (ImGui::SmallButton("Set as default")) { atlas->Fonts[i] = atlas->Fonts[0]; atlas->Fonts[0] = font; } }
ImGui::PushFont(font);
ImGui::Text("The quick brown fox jumps over the lazy dog");
ImGui::PopFont();
if (ImGui::TreeNode("Details"))
{
ImGui::DragFloat("font scale", &font->Scale, 0.005f, 0.3f, 2.0f, "%.1f"); // scale only this font
ImGui::Text("Ascent: %f, Descent: %f, Height: %f", font->Ascent, font->Descent, font->Ascent - font->Descent);
ImGui::Text("Fallback character: '%c' (%d)", font->FallbackChar, font->FallbackChar);
for (int config_i = 0; config_i < font->ConfigDataCount; config_i++)
{
ImFontConfig* cfg = &font->ConfigData[config_i];
ImGui::BulletText("Input %d: \'%s\'\nOversample: (%d,%d), PixelSnapH: %d", config_i, cfg->Name, cfg->OversampleH, cfg->OversampleV, cfg->PixelSnapH);
}
ImGui::TreePop();
}
ImGui::TreePop();
}
static float window_scale = 1.0f;
ImGui::DragFloat("this window scale", &window_scale, 0.005f, 0.3f, 2.0f, "%.1f"); // scale only this window
ImGui::DragFloat("global scale", &ImGui::GetIO().FontGlobalScale, 0.005f, 0.3f, 2.0f, "%.1f"); // scale everything
ImGui::PopItemWidth();
ImGui::SetWindowFontScale(window_scale);
ImGui::TreePop();
}
ImGui::PopItemWidth(); ImGui::PopItemWidth();
} }
@ -1704,9 +1801,9 @@ static void ShowExampleMenuFile()
if (ImGui::MenuItem("Quit", "Alt+F4")) {} if (ImGui::MenuItem("Quit", "Alt+F4")) {}
} }
static void ShowExampleAppAutoResize(bool* opened) static void ShowExampleAppAutoResize(bool* p_open)
{ {
if (!ImGui::Begin("Example: Auto-resizing window", opened, ImGuiWindowFlags_AlwaysAutoResize)) if (!ImGui::Begin("Example: Auto-resizing window", p_open, ImGuiWindowFlags_AlwaysAutoResize))
{ {
ImGui::End(); ImGui::End();
return; return;
@ -1720,10 +1817,47 @@ static void ShowExampleAppAutoResize(bool* opened)
ImGui::End(); ImGui::End();
} }
static void ShowExampleAppFixedOverlay(bool* opened) static void ShowExampleAppConstrainedResize(bool* p_open)
{
struct CustomConstraints // Helper functions to demonstrate programmatic constraints
{
static void Square(ImGuiSizeConstraintCallbackData* data) { data->DesiredSize = ImVec2(IM_MAX(data->DesiredSize.x, data->DesiredSize.y), IM_MAX(data->DesiredSize.x, data->DesiredSize.y)); }
static void Step(ImGuiSizeConstraintCallbackData* data) { float step = (float)(int)(intptr_t)data->UserData; data->DesiredSize = ImVec2((int)(data->DesiredSize.x / step + 0.5f) * step, (int)(data->DesiredSize.y / step + 0.5f) * step); }
};
static int type = 0;
if (type == 0) ImGui::SetNextWindowSizeConstraints(ImVec2(-1, 0), ImVec2(-1, FLT_MAX)); // Vertical only
if (type == 1) ImGui::SetNextWindowSizeConstraints(ImVec2(0, -1), ImVec2(FLT_MAX, -1)); // Horizontal only
if (type == 2) ImGui::SetNextWindowSizeConstraints(ImVec2(100, 100), ImVec2(FLT_MAX, FLT_MAX)); // Width > 100, Height > 100
if (type == 3) ImGui::SetNextWindowSizeConstraints(ImVec2(300, 0), ImVec2(400, FLT_MAX)); // Width 300-400
if (type == 4) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Square); // Always Square
if (type == 5) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Step, (void*)100);// Fixed Step
if (ImGui::Begin("Example: Constrained Resize", p_open))
{
const char* desc[] =
{
"Resize vertical only",
"Resize horizontal only",
"Width > 100, Height > 100",
"Width 300-400",
"Custom: Always Square",
"Custom: Fixed Steps (100)",
};
ImGui::Combo("Constraint", &type, desc, IM_ARRAYSIZE(desc));
if (ImGui::Button("200x200")) ImGui::SetWindowSize(ImVec2(200,200)); ImGui::SameLine();
if (ImGui::Button("500x500")) ImGui::SetWindowSize(ImVec2(500,500)); ImGui::SameLine();
if (ImGui::Button("800x200")) ImGui::SetWindowSize(ImVec2(800,200));
for (int i = 0; i < 10; i++)
ImGui::Text("Hello, sailor! Making this line long enough for the example.");
}
ImGui::End();
}
static void ShowExampleAppFixedOverlay(bool* p_open)
{ {
ImGui::SetNextWindowPos(ImVec2(10,10)); ImGui::SetNextWindowPos(ImVec2(10,10));
if (!ImGui::Begin("Example: Fixed Overlay", opened, ImVec2(0,0), 0.3f, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings)) if (!ImGui::Begin("Example: Fixed Overlay", p_open, ImVec2(0,0), 0.3f, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings))
{ {
ImGui::End(); ImGui::End();
return; return;
@ -1734,10 +1868,8 @@ static void ShowExampleAppFixedOverlay(bool* opened)
ImGui::End(); ImGui::End();
} }
static void ShowExampleAppManipulatingWindowTitle(bool* opened) static void ShowExampleAppManipulatingWindowTitle(bool*)
{ {
(void)opened;
// By default, Windows are uniquely identified by their title. // By default, Windows are uniquely identified by their title.
// You can use the "##" and "###" markers to manipulate the display/ID. Read FAQ at the top of this file! // You can use the "##" and "###" markers to manipulate the display/ID. Read FAQ at the top of this file!
@ -1761,10 +1893,10 @@ static void ShowExampleAppManipulatingWindowTitle(bool* opened)
ImGui::End(); ImGui::End();
} }
static void ShowExampleAppCustomRendering(bool* opened) static void ShowExampleAppCustomRendering(bool* p_open)
{ {
ImGui::SetNextWindowSize(ImVec2(300,350), ImGuiSetCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(350,560), ImGuiSetCond_FirstUseEver);
if (!ImGui::Begin("Example: Custom rendering", opened)) if (!ImGui::Begin("Example: Custom rendering", p_open))
{ {
ImGui::End(); ImGui::End();
return; return;
@ -1773,16 +1905,48 @@ static void ShowExampleAppCustomRendering(bool* opened)
// Tip: If you do a lot of custom rendering, you probably want to use your own geometrical types and benefit of overloaded operators, etc. // Tip: If you do a lot of custom rendering, you probably want to use your own geometrical types and benefit of overloaded operators, etc.
// Define IM_VEC2_CLASS_EXTRA in imconfig.h to create implicit conversions between your types and ImVec2/ImVec4. // Define IM_VEC2_CLASS_EXTRA in imconfig.h to create implicit conversions between your types and ImVec2/ImVec4.
// ImGui defines overloaded operators but they are internal to imgui.cpp and not exposed outside (to avoid messing with your types) // ImGui defines overloaded operators but they are internal to imgui.cpp and not exposed outside (to avoid messing with your types)
// In this example we aren't using the operators. // In this example we are not using the maths operators!
ImDrawList* draw_list = ImGui::GetWindowDrawList();
// Primitives
ImGui::Text("Primitives");
static float sz = 36.0f;
static ImVec4 col = ImVec4(1.0f,1.0f,0.4f,1.0f);
ImGui::DragFloat("Size", &sz, 0.2f, 2.0f, 72.0f, "%.0f");
ImGui::ColorEdit3("Color", &col.x);
{
const ImVec2 p = ImGui::GetCursorScreenPos();
const ImU32 col32 = ImColor(col);
float x = p.x + 4.0f, y = p.y + 4.0f, spacing = 8.0f;
for (int n = 0; n < 2; n++)
{
float thickness = (n == 0) ? 1.0f : 4.0f;
draw_list->AddCircle(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 20, thickness); x += sz+spacing;
draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 0.0f, ~0, thickness); x += sz+spacing;
draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ~0, thickness); x += sz+spacing;
draw_list->AddTriangle(ImVec2(x+sz*0.5f, y), ImVec2(x+sz,y+sz-0.5f), ImVec2(x,y+sz-0.5f), col32, thickness); x += sz+spacing;
draw_list->AddLine(ImVec2(x, y), ImVec2(x+sz, y ), col32, thickness); x += sz+spacing;
draw_list->AddLine(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, thickness); x += sz+spacing;
draw_list->AddLine(ImVec2(x, y), ImVec2(x, y+sz), col32, thickness); x += spacing;
draw_list->AddBezierCurve(ImVec2(x, y), ImVec2(x+sz*1.3f,y+sz*0.3f), ImVec2(x+sz-sz*1.3f,y+sz-sz*0.3f), ImVec2(x+sz, y+sz), col32, thickness);
x = p.x + 4;
y += sz+spacing;
}
draw_list->AddCircleFilled(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 32); x += sz+spacing;
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+sz), col32); x += sz+spacing;
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f); x += sz+spacing;
draw_list->AddTriangleFilled(ImVec2(x+sz*0.5f, y), ImVec2(x+sz,y+sz-0.5f), ImVec2(x,y+sz-0.5f), col32); x += sz+spacing;
draw_list->AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x+sz, y+sz), ImColor(0,0,0), ImColor(255,0,0), ImColor(255,255,0), ImColor(0,255,0));
ImGui::Dummy(ImVec2((sz+spacing)*8, (sz+spacing)*3));
}
ImGui::Separator();
{
static ImVector<ImVec2> points; static ImVector<ImVec2> points;
static bool adding_line = false; static bool adding_line = false;
ImGui::Text("Canvas example");
if (ImGui::Button("Clear")) points.clear(); if (ImGui::Button("Clear")) points.clear();
if (points.Size >= 2) { ImGui::SameLine(); if (ImGui::Button("Undo")) { points.pop_back(); points.pop_back(); } } if (points.Size >= 2) { ImGui::SameLine(); if (ImGui::Button("Undo")) { points.pop_back(); points.pop_back(); } }
ImGui::Text("Left-click and drag to add lines"); ImGui::Text("Left-click and drag to add lines,\nRight-click to undo");
ImGui::Text("Right-click to undo");
ImDrawList* draw_list = ImGui::GetWindowDrawList();
// Here we are using InvisibleButton() as a convenience to 1) advance the cursor and 2) allows us to use IsItemHovered() // Here we are using InvisibleButton() as a convenience to 1) advance the cursor and 2) allows us to use IsItemHovered()
// However you can draw directly and poll mouse/keyboard by yourself. You can manipulate the cursor using GetCursorPos() and SetCursorPos(). // However you can draw directly and poll mouse/keyboard by yourself. You can manipulate the cursor using GetCursorPos() and SetCursorPos().
@ -1791,11 +1955,9 @@ static void ShowExampleAppCustomRendering(bool* opened)
ImVec2 canvas_size = ImGui::GetContentRegionAvail(); // Resize canvas to what's available ImVec2 canvas_size = ImGui::GetContentRegionAvail(); // Resize canvas to what's available
if (canvas_size.x < 50.0f) canvas_size.x = 50.0f; if (canvas_size.x < 50.0f) canvas_size.x = 50.0f;
if (canvas_size.y < 50.0f) canvas_size.y = 50.0f; if (canvas_size.y < 50.0f) canvas_size.y = 50.0f;
draw_list->AddRectFilledMultiColor(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), ImColor(0,0,0), ImColor(255,0,0), ImColor(255,255,0), ImColor(0,255,0)); draw_list->AddRectFilledMultiColor(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), ImColor(50,50,50), ImColor(50,50,60), ImColor(60,60,70), ImColor(50,50,60));
draw_list->AddRect(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), ImColor(255,255,255)); draw_list->AddRect(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), ImColor(255,255,255));
draw_list->AddBezierCurve(ImVec2(canvas_pos.x+20,canvas_pos.y+20), ImVec2(canvas_pos.x+100,canvas_pos.y+20), ImVec2(canvas_pos.x+canvas_size.x-100,canvas_pos.y+canvas_size.y-20), ImVec2(canvas_pos.x+canvas_size.x-20,canvas_pos.y+canvas_size.y-20), ImColor(255,200,0), 5.0f);
bool adding_preview = false; bool adding_preview = false;
ImGui::InvisibleButton("canvas", canvas_size); ImGui::InvisibleButton("canvas", canvas_size);
if (ImGui::IsItemHovered()) if (ImGui::IsItemHovered())
@ -1820,12 +1982,13 @@ static void ShowExampleAppCustomRendering(bool* opened)
points.pop_back(); points.pop_back();
} }
} }
draw_list->PushClipRect(ImVec4(canvas_pos.x, canvas_pos.y, canvas_pos.x+canvas_size.x, canvas_pos.y+canvas_size.y)); // clip lines within the canvas (if we resize it, etc.) draw_list->PushClipRect(canvas_pos, ImVec2(canvas_pos.x+canvas_size.x, canvas_pos.y+canvas_size.y)); // clip lines within the canvas (if we resize it, etc.)
for (int i = 0; i < points.Size - 1; i += 2) for (int i = 0; i < points.Size - 1; i += 2)
draw_list->AddLine(ImVec2(canvas_pos.x + points[i].x, canvas_pos.y + points[i].y), ImVec2(canvas_pos.x + points[i+1].x, canvas_pos.y + points[i+1].y), 0xFF00FFFF, 2.0f); draw_list->AddLine(ImVec2(canvas_pos.x + points[i].x, canvas_pos.y + points[i].y), ImVec2(canvas_pos.x + points[i+1].x, canvas_pos.y + points[i+1].y), 0xFF00FFFF, 2.0f);
draw_list->PopClipRect(); draw_list->PopClipRect();
if (adding_preview) if (adding_preview)
points.pop_back(); points.pop_back();
}
ImGui::End(); ImGui::End();
} }
@ -1842,19 +2005,26 @@ struct ExampleAppConsole
ExampleAppConsole() ExampleAppConsole()
{ {
ClearLog(); ClearLog();
memset(InputBuf, 0, sizeof(InputBuf));
HistoryPos = -1; HistoryPos = -1;
Commands.push_back("HELP"); Commands.push_back("HELP");
Commands.push_back("HISTORY"); Commands.push_back("HISTORY");
Commands.push_back("CLEAR"); Commands.push_back("CLEAR");
Commands.push_back("CLASSIFY"); // "classify" is here to provide an example of "C"+[tab] completing to "CL" and displaying matches. Commands.push_back("CLASSIFY"); // "classify" is here to provide an example of "C"+[tab] completing to "CL" and displaying matches.
AddLog("Welcome to ImGui!");
} }
~ExampleAppConsole() ~ExampleAppConsole()
{ {
ClearLog(); ClearLog();
for (int i = 0; i < Items.Size; i++) for (int i = 0; i < History.Size; i++)
free(History[i]); free(History[i]);
} }
// Portable helpers
static int Stricmp(const char* str1, const char* str2) { int d; while ((d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; } return d; }
static int Strnicmp(const char* str1, const char* str2, int n) { int d = 0; while (n > 0 && (d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; n--; } return d; }
static char* Strdup(const char *str) { size_t len = strlen(str) + 1; void* buff = malloc(len); return (char*)memcpy(buff, (const void*)str, len); }
void ClearLog() void ClearLog()
{ {
for (int i = 0; i < Items.Size; i++) for (int i = 0; i < Items.Size; i++)
@ -1871,14 +2041,14 @@ struct ExampleAppConsole
vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args); vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args);
buf[IM_ARRAYSIZE(buf)-1] = 0; buf[IM_ARRAYSIZE(buf)-1] = 0;
va_end(args); va_end(args);
Items.push_back(strdup(buf)); Items.push_back(Strdup(buf));
ScrollToBottom = true; ScrollToBottom = true;
} }
void Draw(const char* title, bool* opened) void Draw(const char* title, bool* p_open)
{ {
ImGui::SetNextWindowSize(ImVec2(520,600), ImGuiSetCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(520,600), ImGuiSetCond_FirstUseEver);
if (!ImGui::Begin(title, opened)) if (!ImGui::Begin(title, p_open))
{ {
ImGui::End(); ImGui::End();
return; return;
@ -1891,7 +2061,8 @@ struct ExampleAppConsole
if (ImGui::SmallButton("Add Dummy Text")) { AddLog("%d some text", Items.Size); AddLog("some more text"); AddLog("display very important message here!"); } ImGui::SameLine(); if (ImGui::SmallButton("Add Dummy Text")) { AddLog("%d some text", Items.Size); AddLog("some more text"); AddLog("display very important message here!"); } ImGui::SameLine();
if (ImGui::SmallButton("Add Dummy Error")) AddLog("[error] something went wrong"); ImGui::SameLine(); if (ImGui::SmallButton("Add Dummy Error")) AddLog("[error] something went wrong"); ImGui::SameLine();
if (ImGui::SmallButton("Clear")) ClearLog(); if (ImGui::SmallButton("Clear")) ClearLog(); ImGui::SameLine();
if (ImGui::SmallButton("Scroll to bottom")) ScrollToBottom = true;
//static float t = 0.0f; if (ImGui::GetTime() - t > 0.02f) { t = ImGui::GetTime(); AddLog("Spam %f", t); } //static float t = 0.0f; if (ImGui::GetTime() - t > 0.02f) { t = ImGui::GetTime(); AddLog("Spam %f", t); }
ImGui::Separator(); ImGui::Separator();
@ -1902,24 +2073,33 @@ struct ExampleAppConsole
ImGui::PopStyleVar(); ImGui::PopStyleVar();
ImGui::Separator(); ImGui::Separator();
// Display every line as a separate entry so we can change their color or add custom widgets. If you only want raw text you can use ImGui::TextUnformatted(log.begin(), log.end());
// NB- if you have thousands of entries this approach may be too inefficient. You can seek and display only the lines that are visible - CalcListClipping() is a helper to compute this information.
// If your items are of variable size you may want to implement code similar to what CalcListClipping() does. Or split your data into fixed height items to allow random-seeking into your list.
ImGui::BeginChild("ScrollingRegion", ImVec2(0,-ImGui::GetItemsLineHeightWithSpacing()), false, ImGuiWindowFlags_HorizontalScrollbar); ImGui::BeginChild("ScrollingRegion", ImVec2(0,-ImGui::GetItemsLineHeightWithSpacing()), false, ImGuiWindowFlags_HorizontalScrollbar);
if (ImGui::BeginPopupContextWindow()) if (ImGui::BeginPopupContextWindow())
{ {
if (ImGui::Selectable("Clear")) ClearLog(); if (ImGui::Selectable("Clear")) ClearLog();
ImGui::EndPopup(); ImGui::EndPopup();
} }
// Display every line as a separate entry so we can change their color or add custom widgets. If you only want raw text you can use ImGui::TextUnformatted(log.begin(), log.end());
// NB- if you have thousands of entries this approach may be too inefficient and may require user-side clipping to only process visible items.
// You can seek and display only the lines that are visible using the ImGuiListClipper helper, if your elements are evenly spaced and you have cheap random access to the elements.
// To use the clipper we could replace the 'for (int i = 0; i < Items.Size; i++)' loop with:
// ImGuiListClipper clipper(Items.Size);
// while (clipper.Step())
// for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
// However take note that you can not use this code as is if a filter is active because it breaks the 'cheap random-access' property. We would need random-access on the post-filtered list.
// A typical application wanting coarse clipping and filtering may want to pre-compute an array of indices that passed the filtering test, recomputing this array when user changes the filter,
// and appending newly elements as they are inserted. This is left as a task to the user until we can manage to improve this example code!
// If your items are of variable size you may want to implement code similar to what ImGuiListClipper does. Or split your data into fixed height items to allow random-seeking into your list.
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4,1)); // Tighten spacing ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4,1)); // Tighten spacing
for (int i = 0; i < Items.Size; i++) for (int i = 0; i < Items.Size; i++)
{ {
const char* item = Items[i]; const char* item = Items[i];
if (!filter.PassFilter(item)) if (!filter.PassFilter(item))
continue; continue;
ImVec4 col = ImColor(255,255,255); // A better implementation may store a type per-item. For the sample let's just parse the text. ImVec4 col = ImVec4(1.0f,1.0f,1.0f,1.0f); // A better implementation may store a type per-item. For the sample let's just parse the text.
if (strstr(item, "[error]")) col = ImColor(255,100,100); if (strstr(item, "[error]")) col = ImColor(1.0f,0.4f,0.4f,1.0f);
else if (strncmp(item, "# ", 2) == 0) col = ImColor(255,200,150); else if (strncmp(item, "# ", 2) == 0) col = ImColor(1.0f,0.78f,0.58f,1.0f);
ImGui::PushStyleColor(ImGuiCol_Text, col); ImGui::PushStyleColor(ImGuiCol_Text, col);
ImGui::TextUnformatted(item); ImGui::TextUnformatted(item);
ImGui::PopStyleColor(); ImGui::PopStyleColor();
@ -1943,14 +2123,11 @@ struct ExampleAppConsole
// Demonstrate keeping auto focus on the input box // Demonstrate keeping auto focus on the input box
if (ImGui::IsItemHovered() || (ImGui::IsRootWindowOrAnyChildFocused() && !ImGui::IsAnyItemActive() && !ImGui::IsMouseClicked(0))) if (ImGui::IsItemHovered() || (ImGui::IsRootWindowOrAnyChildFocused() && !ImGui::IsAnyItemActive() && !ImGui::IsMouseClicked(0)))
ImGui::SetKeyboardFocusHere(-1); // Auto focus ImGui::SetKeyboardFocusHere(-1); // Auto focus previous widget
ImGui::End(); ImGui::End();
} }
static int Stricmp(const char* str1, const char* str2) { int d; while ((d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; } return d; }
static int Strnicmp(const char* str1, const char* str2, int count) { int d = 0; while (count > 0 && (d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; count--; } return d; }
void ExecCommand(const char* command_line) void ExecCommand(const char* command_line)
{ {
AddLog("# %s\n", command_line); AddLog("# %s\n", command_line);
@ -1964,7 +2141,7 @@ struct ExampleAppConsole
History.erase(History.begin() + i); History.erase(History.begin() + i);
break; break;
} }
History.push_back(strdup(command_line)); History.push_back(Strdup(command_line));
// Process command // Process command
if (Stricmp(command_line, "CLEAR") == 0) if (Stricmp(command_line, "CLEAR") == 0)
@ -2085,9 +2262,8 @@ struct ExampleAppConsole
// A better implementation would preserve the data on the current input line along with cursor position. // A better implementation would preserve the data on the current input line along with cursor position.
if (prev_history_pos != HistoryPos) if (prev_history_pos != HistoryPos)
{ {
snprintf(data->Buf, data->BufSize, "%s", (HistoryPos >= 0) ? History[HistoryPos] : ""); data->CursorPos = data->SelectionStart = data->SelectionEnd = data->BufTextLen = (int)snprintf(data->Buf, (size_t)data->BufSize, "%s", (HistoryPos >= 0) ? History[HistoryPos] : "");
data->BufDirty = true; data->BufDirty = true;
data->CursorPos = data->SelectionStart = data->SelectionEnd = (int)strlen(data->Buf);
} }
} }
} }
@ -2095,10 +2271,10 @@ struct ExampleAppConsole
} }
}; };
static void ShowExampleAppConsole(bool* opened) static void ShowExampleAppConsole(bool* p_open)
{ {
static ExampleAppConsole console; static ExampleAppConsole console;
console.Draw("Example: Console", opened); console.Draw("Example: Console", p_open);
} }
// Usage: // Usage:
@ -2127,10 +2303,10 @@ struct ExampleAppLog
ScrollToBottom = true; ScrollToBottom = true;
} }
void Draw(const char* title, bool* p_opened = NULL) void Draw(const char* title, bool* p_open = NULL)
{ {
ImGui::SetNextWindowSize(ImVec2(500,400), ImGuiSetCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(500,400), ImGuiSetCond_FirstUseEver);
ImGui::Begin(title, p_opened); ImGui::Begin(title, p_open);
if (ImGui::Button("Clear")) Clear(); if (ImGui::Button("Clear")) Clear();
ImGui::SameLine(); ImGui::SameLine();
bool copy = ImGui::Button("Copy"); bool copy = ImGui::Button("Copy");
@ -2165,7 +2341,7 @@ struct ExampleAppLog
} }
}; };
static void ShowExampleAppLog(bool* opened) static void ShowExampleAppLog(bool* p_open)
{ {
static ExampleAppLog log; static ExampleAppLog log;
@ -2179,19 +2355,19 @@ static void ShowExampleAppLog(bool* opened)
last_time = time; last_time = time;
} }
log.Draw("Example: Log", opened); log.Draw("Example: Log", p_open);
} }
static void ShowExampleAppLayout(bool* opened) static void ShowExampleAppLayout(bool* p_open)
{ {
ImGui::SetNextWindowSize(ImVec2(500, 440), ImGuiSetCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(500, 440), ImGuiSetCond_FirstUseEver);
if (ImGui::Begin("Example: Layout", opened, ImGuiWindowFlags_MenuBar)) if (ImGui::Begin("Example: Layout", p_open, ImGuiWindowFlags_MenuBar))
{ {
if (ImGui::BeginMenuBar()) if (ImGui::BeginMenuBar())
{ {
if (ImGui::BeginMenu("File")) if (ImGui::BeginMenu("File"))
{ {
if (ImGui::MenuItem("Close")) *opened = false; if (ImGui::MenuItem("Close")) *p_open = false;
ImGui::EndMenu(); ImGui::EndMenu();
} }
ImGui::EndMenuBar(); ImGui::EndMenuBar();
@ -2227,10 +2403,10 @@ static void ShowExampleAppLayout(bool* opened)
ImGui::End(); ImGui::End();
} }
static void ShowExampleAppPropertyEditor(bool* opened) static void ShowExampleAppPropertyEditor(bool* p_open)
{ {
ImGui::SetNextWindowSize(ImVec2(430,450), ImGuiSetCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(430,450), ImGuiSetCond_FirstUseEver);
if (!ImGui::Begin("Example: Property editor", opened)) if (!ImGui::Begin("Example: Property editor", p_open))
{ {
ImGui::End(); ImGui::End();
return; return;
@ -2244,16 +2420,16 @@ static void ShowExampleAppPropertyEditor(bool* opened)
struct funcs struct funcs
{ {
static void ShowDummyObject(const char* prefix, ImU32 uid) static void ShowDummyObject(const char* prefix, int uid)
{ {
ImGui::PushID(uid); // Use object uid as identifier. Most commonly you could also use the object pointer as a base ID. ImGui::PushID(uid); // Use object uid as identifier. Most commonly you could also use the object pointer as a base ID.
ImGui::AlignFirstTextHeightToWidgets(); // Text and Tree nodes are less high than regular widgets, here we add vertical spacing to make the tree lines equal high. ImGui::AlignFirstTextHeightToWidgets(); // Text and Tree nodes are less high than regular widgets, here we add vertical spacing to make the tree lines equal high.
bool opened = ImGui::TreeNode("Object", "%s_%u", prefix, uid); bool node_open = ImGui::TreeNode("Object", "%s_%u", prefix, uid);
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::AlignFirstTextHeightToWidgets(); ImGui::AlignFirstTextHeightToWidgets();
ImGui::Text("my sailor is rich"); ImGui::Text("my sailor is rich");
ImGui::NextColumn(); ImGui::NextColumn();
if (opened) if (node_open)
{ {
static float dummy_members[8] = { 0.0f,0.0f,1.0f,3.1416f,100.0f,999.0f }; static float dummy_members[8] = { 0.0f,0.0f,1.0f,3.1416f,100.0f,999.0f };
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
@ -2261,7 +2437,7 @@ static void ShowExampleAppPropertyEditor(bool* opened)
ImGui::PushID(i); // Use field index as identifier. ImGui::PushID(i); // Use field index as identifier.
if (i < 2) if (i < 2)
{ {
ShowDummyObject("Child", ImGui::GetID("foo")); ShowDummyObject("Child", 424242);
} }
else else
{ {
@ -2299,10 +2475,10 @@ static void ShowExampleAppPropertyEditor(bool* opened)
ImGui::End(); ImGui::End();
} }
static void ShowExampleAppLongText(bool* opened) static void ShowExampleAppLongText(bool* p_open)
{ {
ImGui::SetNextWindowSize(ImVec2(520,600), ImGuiSetCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(520,600), ImGuiSetCond_FirstUseEver);
if (!ImGui::Begin("Example: Long text display", opened)) if (!ImGui::Begin("Example: Long text display", p_open))
{ {
ImGui::End(); ImGui::End();
return; return;
@ -2333,10 +2509,10 @@ static void ShowExampleAppLongText(bool* opened)
{ {
// Multiple calls to Text(), manually coarsely clipped - demonstrate how to use the ImGuiListClipper helper. // Multiple calls to Text(), manually coarsely clipped - demonstrate how to use the ImGuiListClipper helper.
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0)); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0));
ImGuiListClipper clipper(lines, ImGui::GetTextLineHeight()); ImGuiListClipper clipper(lines);
while (clipper.Step())
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
ImGui::Text("%i The quick brown fox jumps over the lazy dog\n", i); ImGui::Text("%i The quick brown fox jumps over the lazy dog", i);
clipper.End();
ImGui::PopStyleVar(); ImGui::PopStyleVar();
break; break;
} }
@ -2344,7 +2520,7 @@ static void ShowExampleAppLongText(bool* opened)
// Multiple calls to Text(), not clipped (slow) // Multiple calls to Text(), not clipped (slow)
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0)); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0));
for (int i = 0; i < lines; i++) for (int i = 0; i < lines; i++)
ImGui::Text("%i The quick brown fox jumps over the lazy dog\n", i); ImGui::Text("%i The quick brown fox jumps over the lazy dog", i);
ImGui::PopStyleVar(); ImGui::PopStyleVar();
break; break;
} }
@ -2356,7 +2532,7 @@ static void ShowExampleAppLongText(bool* opened)
#else #else
void ImGui::ShowTestWindow(bool*) {} void ImGui::ShowTestWindow(bool*) {}
void ImGui::ShowUserGuide(bool*) {} void ImGui::ShowUserGuide() {}
void ImGui::ShowStyleEditor(bool*) {} void ImGui::ShowStyleEditor(ImGuiStyle*) {}
#endif #endif

View File

@ -1,4 +1,4 @@
// dear imgui, v1.47 // dear imgui, v1.49
// (drawing and font code) // (drawing and font code)
// Contains implementation for // Contains implementation for
@ -14,11 +14,11 @@
#include "imgui.h" #include "imgui.h"
#define IMGUI_DEFINE_MATH_OPERATORS #define IMGUI_DEFINE_MATH_OPERATORS
#define IMGUI_DEFINE_PLACEMENT_NEW
#include "imgui_internal.h" #include "imgui_internal.h"
#include <stdio.h> // vsnprintf, sscanf, printf #include <stdio.h> // vsnprintf, sscanf, printf
#include <new> // new (ptr) #if !defined(alloca) && !defined(__FreeBSD__) && !defined(__DragonFly__)
#if !defined(alloca) && !defined(__FreeBSD__)
#ifdef _WIN32 #ifdef _WIN32
#include <malloc.h> // alloca #include <malloc.h> // alloca
#else #else
@ -31,8 +31,17 @@
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen #pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
#define snprintf _snprintf #define snprintf _snprintf
#endif #endif
#ifdef __GNUC__
#ifdef __clang__
#pragma clang diagnostic ignored "-Wold-style-cast" // warning : use of old-style cast // yes, they are more terse.
#pragma clang diagnostic ignored "-Wfloat-equal" // warning : comparing floating point with == or != is unsafe // storing and comparing against same constants ok.
#pragma clang diagnostic ignored "-Wglobal-constructors" // warning : declaration requires a global destructor // similar to above, not sure what the exact difference it.
#pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness //
#pragma clang diagnostic ignored "-Wreserved-id-macro" // warning : macro name is a reserved identifier //
#elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used #pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function
#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value
#endif #endif
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -55,10 +64,16 @@ namespace IMGUI_STB_NAMESPACE
#ifdef __clang__ #ifdef __clang__
#pragma clang diagnostic push #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wold-style-cast" // warning : use of old-style cast // yes, they are more terse.
#pragma clang diagnostic ignored "-Wunused-function" #pragma clang diagnostic ignored "-Wunused-function"
#pragma clang diagnostic ignored "-Wmissing-prototypes" #pragma clang diagnostic ignored "-Wmissing-prototypes"
#endif #endif
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtype-limits" // warning: comparison is always true due to limited range of data type [-Wtype-limits]
#endif
#define STBRP_ASSERT(x) IM_ASSERT(x) #define STBRP_ASSERT(x) IM_ASSERT(x)
#ifndef IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION #ifndef IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
#define STBRP_STATIC #define STBRP_STATIC
@ -77,6 +92,10 @@ namespace IMGUI_STB_NAMESPACE
#endif #endif
#include "stb_truetype.h" #include "stb_truetype.h"
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#ifdef __clang__ #ifdef __clang__
#pragma clang diagnostic pop #pragma clang diagnostic pop
#endif #endif
@ -205,20 +224,29 @@ void ImDrawList::UpdateTextureID()
#undef GetCurrentClipRect #undef GetCurrentClipRect
#undef GetCurrentTextureId #undef GetCurrentTextureId
// Scissoring. The values in clip_rect are x1, y1, x2, y2. Only apply to rendering! Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling) // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling)
void ImDrawList::PushClipRect(const ImVec4& clip_rect) void ImDrawList::PushClipRect(ImVec2 cr_min, ImVec2 cr_max, bool intersect_with_current_clip_rect)
{ {
_ClipRectStack.push_back(clip_rect); ImVec4 cr(cr_min.x, cr_min.y, cr_max.x, cr_max.y);
if (intersect_with_current_clip_rect && _ClipRectStack.Size)
{
ImVec4 current = _ClipRectStack.Data[_ClipRectStack.Size-1];
if (cr.x < current.x) cr.x = current.x;
if (cr.y < current.y) cr.y = current.y;
if (cr.z > current.z) cr.z = current.z;
if (cr.w > current.w) cr.w = current.w;
}
cr.z = ImMax(cr.x, cr.z);
cr.w = ImMax(cr.y, cr.w);
_ClipRectStack.push_back(cr);
UpdateClipRect(); UpdateClipRect();
} }
void ImDrawList::PushClipRectFullScreen() void ImDrawList::PushClipRectFullScreen()
{ {
PushClipRect(GNullClipRect); PushClipRect(ImVec2(GNullClipRect.x, GNullClipRect.y), ImVec2(GNullClipRect.z, GNullClipRect.w));
//PushClipRect(GetVisibleRect()); // FIXME-OPT: This would be more correct but we're not supposed to access ImGuiContext from here?
// FIXME-OPT: This would be more correct but we're not supposed to access ImGuiState from here?
//ImGuiState& g = *GImGui;
//PushClipRect(GetVisibleRect());
} }
void ImDrawList::PopClipRect() void ImDrawList::PopClipRect()
@ -257,7 +285,7 @@ void ImDrawList::ChannelsSplit(int channels_count)
{ {
if (i >= old_channels_count) if (i >= old_channels_count)
{ {
new(&_Channels[i]) ImDrawChannel(); IM_PLACEMENT_NEW(&_Channels[i]) ImDrawChannel();
} }
else else
{ {
@ -335,13 +363,13 @@ void ImDrawList::PrimReserve(int idx_count, int vtx_count)
_IdxWritePtr = IdxBuffer.Data + idx_buffer_size; _IdxWritePtr = IdxBuffer.Data + idx_buffer_size;
} }
// Fully unrolled with inline call to keep our debug builds decently fast.
void ImDrawList::PrimRect(const ImVec2& a, const ImVec2& c, ImU32 col) void ImDrawList::PrimRect(const ImVec2& a, const ImVec2& c, ImU32 col)
{ {
const ImVec2 uv = GImGui->FontTexUvWhitePixel; ImVec2 b(c.x, a.y), d(a.x, c.y), uv(GImGui->FontTexUvWhitePixel);
const ImVec2 b(c.x, a.y); ImDrawIdx idx = (ImDrawIdx)_VtxCurrentIdx;
const ImVec2 d(a.x, c.y); _IdxWritePtr[0] = idx; _IdxWritePtr[1] = (ImDrawIdx)(idx+1); _IdxWritePtr[2] = (ImDrawIdx)(idx+2);
_IdxWritePtr[0] = (ImDrawIdx)(_VtxCurrentIdx); _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx+1); _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx+2); _IdxWritePtr[3] = idx; _IdxWritePtr[4] = (ImDrawIdx)(idx+2); _IdxWritePtr[5] = (ImDrawIdx)(idx+3);
_IdxWritePtr[3] = (ImDrawIdx)(_VtxCurrentIdx); _IdxWritePtr[4] = (ImDrawIdx)(_VtxCurrentIdx+2); _IdxWritePtr[5] = (ImDrawIdx)(_VtxCurrentIdx+3);
_VtxWritePtr[0].pos = a; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; _VtxWritePtr[0].pos = a; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col;
_VtxWritePtr[1].pos = b; _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col; _VtxWritePtr[1].pos = b; _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col;
_VtxWritePtr[2].pos = c; _VtxWritePtr[2].uv = uv; _VtxWritePtr[2].col = col; _VtxWritePtr[2].pos = c; _VtxWritePtr[2].uv = uv; _VtxWritePtr[2].col = col;
@ -353,12 +381,24 @@ void ImDrawList::PrimRect(const ImVec2& a, const ImVec2& c, ImU32 col)
void ImDrawList::PrimRectUV(const ImVec2& a, const ImVec2& c, const ImVec2& uv_a, const ImVec2& uv_c, ImU32 col) void ImDrawList::PrimRectUV(const ImVec2& a, const ImVec2& c, const ImVec2& uv_a, const ImVec2& uv_c, ImU32 col)
{ {
const ImVec2 b(c.x, a.y); ImVec2 b(c.x, a.y), d(a.x, c.y), uv_b(uv_c.x, uv_a.y), uv_d(uv_a.x, uv_c.y);
const ImVec2 d(a.x, c.y); ImDrawIdx idx = (ImDrawIdx)_VtxCurrentIdx;
const ImVec2 uv_b(uv_c.x, uv_a.y); _IdxWritePtr[0] = idx; _IdxWritePtr[1] = (ImDrawIdx)(idx+1); _IdxWritePtr[2] = (ImDrawIdx)(idx+2);
const ImVec2 uv_d(uv_a.x, uv_c.y); _IdxWritePtr[3] = idx; _IdxWritePtr[4] = (ImDrawIdx)(idx+2); _IdxWritePtr[5] = (ImDrawIdx)(idx+3);
_IdxWritePtr[0] = (ImDrawIdx)(_VtxCurrentIdx); _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx+1); _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx+2); _VtxWritePtr[0].pos = a; _VtxWritePtr[0].uv = uv_a; _VtxWritePtr[0].col = col;
_IdxWritePtr[3] = (ImDrawIdx)(_VtxCurrentIdx); _IdxWritePtr[4] = (ImDrawIdx)(_VtxCurrentIdx+2); _IdxWritePtr[5] = (ImDrawIdx)(_VtxCurrentIdx+3); _VtxWritePtr[1].pos = b; _VtxWritePtr[1].uv = uv_b; _VtxWritePtr[1].col = col;
_VtxWritePtr[2].pos = c; _VtxWritePtr[2].uv = uv_c; _VtxWritePtr[2].col = col;
_VtxWritePtr[3].pos = d; _VtxWritePtr[3].uv = uv_d; _VtxWritePtr[3].col = col;
_VtxWritePtr += 4;
_VtxCurrentIdx += 4;
_IdxWritePtr += 6;
}
void ImDrawList::PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a, const ImVec2& uv_b, const ImVec2& uv_c, const ImVec2& uv_d, ImU32 col)
{
ImDrawIdx idx = (ImDrawIdx)_VtxCurrentIdx;
_IdxWritePtr[0] = idx; _IdxWritePtr[1] = (ImDrawIdx)(idx+1); _IdxWritePtr[2] = (ImDrawIdx)(idx+2);
_IdxWritePtr[3] = idx; _IdxWritePtr[4] = (ImDrawIdx)(idx+2); _IdxWritePtr[5] = (ImDrawIdx)(idx+3);
_VtxWritePtr[0].pos = a; _VtxWritePtr[0].uv = uv_a; _VtxWritePtr[0].col = col; _VtxWritePtr[0].pos = a; _VtxWritePtr[0].uv = uv_a; _VtxWritePtr[0].col = col;
_VtxWritePtr[1].pos = b; _VtxWritePtr[1].uv = uv_b; _VtxWritePtr[1].col = col; _VtxWritePtr[1].pos = b; _VtxWritePtr[1].uv = uv_b; _VtxWritePtr[1].col = col;
_VtxWritePtr[2].pos = c; _VtxWritePtr[2].uv = uv_c; _VtxWritePtr[2].col = col; _VtxWritePtr[2].pos = c; _VtxWritePtr[2].uv = uv_c; _VtxWritePtr[2].col = col;
@ -762,12 +802,13 @@ void ImDrawList::AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thic
PathStroke(col, false, thickness); PathStroke(col, false, thickness);
} }
void ImDrawList::AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, int rounding_corners) // a: upper-left, b: lower-right. we don't render 1 px sized rectangles properly.
void ImDrawList::AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, int rounding_corners, float thickness)
{ {
if ((col >> 24) == 0) if ((col >> 24) == 0)
return; return;
PathRect(a + ImVec2(0.5f,0.5f), b + ImVec2(0.5f,0.5f), rounding, rounding_corners); PathRect(a + ImVec2(0.5f,0.5f), b - ImVec2(0.5f,0.5f), rounding, rounding_corners);
PathStroke(col, true); PathStroke(col, true, thickness);
} }
void ImDrawList::AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, int rounding_corners) void ImDrawList::AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, int rounding_corners)
@ -801,6 +842,41 @@ void ImDrawList::AddRectFilledMultiColor(const ImVec2& a, const ImVec2& c, ImU32
PrimWriteVtx(ImVec2(a.x, c.y), uv, col_bot_left); PrimWriteVtx(ImVec2(a.x, c.y), uv, col_bot_left);
} }
void ImDrawList::AddQuad(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col, float thickness)
{
if ((col >> 24) == 0)
return;
PathLineTo(a);
PathLineTo(b);
PathLineTo(c);
PathLineTo(d);
PathStroke(col, true, thickness);
}
void ImDrawList::AddQuadFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col)
{
if ((col >> 24) == 0)
return;
PathLineTo(a);
PathLineTo(b);
PathLineTo(c);
PathLineTo(d);
PathFill(col);
}
void ImDrawList::AddTriangle(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col, float thickness)
{
if ((col >> 24) == 0)
return;
PathLineTo(a);
PathLineTo(b);
PathLineTo(c);
PathStroke(col, true, thickness);
}
void ImDrawList::AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col) void ImDrawList::AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col)
{ {
if ((col >> 24) == 0) if ((col >> 24) == 0)
@ -812,14 +888,14 @@ void ImDrawList::AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec
PathFill(col); PathFill(col);
} }
void ImDrawList::AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments) void ImDrawList::AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments, float thickness)
{ {
if ((col >> 24) == 0) if ((col >> 24) == 0)
return; return;
const float a_max = IM_PI*2.0f * ((float)num_segments - 1.0f) / (float)num_segments; const float a_max = IM_PI*2.0f * ((float)num_segments - 1.0f) / (float)num_segments;
PathArcTo(centre, radius, 0.0f, a_max, num_segments); PathArcTo(centre, radius-0.5f, 0.0f, a_max, num_segments);
PathStroke(col, true); PathStroke(col, true, thickness);
} }
void ImDrawList::AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments) void ImDrawList::AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments)
@ -852,15 +928,14 @@ void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos,
if (text_begin == text_end) if (text_begin == text_end)
return; return;
IM_ASSERT(font->ContainerAtlas->TexID == _TextureIdStack.back()); // Use high-level ImGui::PushFont() or low-level ImDrawList::PushTextureId() to change font. // Note: This is one of the few instance of breaking the encapsulation of ImDrawList, as we pull this from ImGui state, but it is just SO useful.
// Might just move Font/FontSize to ImDrawList?
if (font == NULL)
font = GImGui->Font;
if (font_size == 0.0f)
font_size = GImGui->FontSize;
// reserve vertices for worse case (over-reserving is useful and easily amortized) IM_ASSERT(font->ContainerAtlas->TexID == _TextureIdStack.back()); // Use high-level ImGui::PushFont() or low-level ImDrawList::PushTextureId() to change font.
const int char_count = (int)(text_end - text_begin);
const int vtx_count_max = char_count * 4;
const int idx_count_max = char_count * 6;
const int vtx_begin = VtxBuffer.Size;
const int idx_begin = IdxBuffer.Size;
PrimReserve(idx_count_max, vtx_count_max);
ImVec4 clip_rect = _ClipRectStack.back(); ImVec4 clip_rect = _ClipRectStack.back();
if (cpu_fine_clip_rect) if (cpu_fine_clip_rect)
@ -870,26 +945,11 @@ void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos,
clip_rect.z = ImMin(clip_rect.z, cpu_fine_clip_rect->z); clip_rect.z = ImMin(clip_rect.z, cpu_fine_clip_rect->z);
clip_rect.w = ImMin(clip_rect.w, cpu_fine_clip_rect->w); clip_rect.w = ImMin(clip_rect.w, cpu_fine_clip_rect->w);
} }
font->RenderText(font_size, pos, col, clip_rect, text_begin, text_end, this, wrap_width, cpu_fine_clip_rect != NULL); font->RenderText(this, font_size, pos, col, clip_rect, text_begin, text_end, wrap_width, cpu_fine_clip_rect != NULL);
// give back unused vertices
// FIXME-OPT: clean this up
VtxBuffer.resize((int)(_VtxWritePtr - VtxBuffer.Data));
IdxBuffer.resize((int)(_IdxWritePtr - IdxBuffer.Data));
int vtx_unused = vtx_count_max - (VtxBuffer.Size - vtx_begin);
int idx_unused = idx_count_max - (IdxBuffer.Size - idx_begin);
CmdBuffer.back().ElemCount -= idx_unused;
_VtxWritePtr -= vtx_unused;
_IdxWritePtr -= idx_unused;
_VtxCurrentIdx = (ImDrawIdx)VtxBuffer.Size;
} }
// This is one of the few function breaking the encapsulation of ImDrawLst, but it is just so useful.
void ImDrawList::AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end) void ImDrawList::AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end)
{ {
if ((col >> 24) == 0)
return;
AddText(GImGui->Font, GImGui->FontSize, pos, col, text_begin, text_end); AddText(GImGui->Font, GImGui->FontSize, pos, col, text_begin, text_end);
} }
@ -1075,12 +1135,13 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg)
if (!font_cfg->MergeMode) if (!font_cfg->MergeMode)
{ {
ImFont* font = (ImFont*)ImGui::MemAlloc(sizeof(ImFont)); ImFont* font = (ImFont*)ImGui::MemAlloc(sizeof(ImFont));
new (font) ImFont(); IM_PLACEMENT_NEW(font) ImFont();
Fonts.push_back(font); Fonts.push_back(font);
} }
ConfigData.push_back(*font_cfg); ConfigData.push_back(*font_cfg);
ImFontConfig& new_font_cfg = ConfigData.back(); ImFontConfig& new_font_cfg = ConfigData.back();
if (!new_font_cfg.DstFont)
new_font_cfg.DstFont = Fonts.back(); new_font_cfg.DstFont = Fonts.back();
if (!new_font_cfg.FontDataOwnedByAtlas) if (!new_font_cfg.FontDataOwnedByAtlas)
{ {
@ -1091,7 +1152,7 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg)
// Invalidate texture // Invalidate texture
ClearTexData(); ClearTexData();
return Fonts.back(); return new_font_cfg.DstFont;
} }
// Default font TTF is compressed with stb_compress then base85 encoded (see extra_fonts/binary_to_compressed_c.cpp for encoder) // Default font TTF is compressed with stb_compress then base85 encoded (see extra_fonts/binary_to_compressed_c.cpp for encoder)
@ -1168,13 +1229,13 @@ ImFont* ImFontAtlas::AddFontFromMemoryCompressedTTF(const void* compressed_ttf_d
ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig(); ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig();
IM_ASSERT(font_cfg.FontData == NULL); IM_ASSERT(font_cfg.FontData == NULL);
font_cfg.FontDataOwnedByAtlas = true; font_cfg.FontDataOwnedByAtlas = true;
return AddFontFromMemoryTTF(buf_decompressed_data, (int)buf_decompressed_size, size_pixels, font_cfg_template, glyph_ranges); return AddFontFromMemoryTTF(buf_decompressed_data, (int)buf_decompressed_size, size_pixels, &font_cfg, glyph_ranges);
} }
ImFont* ImFontAtlas::AddFontFromMemoryCompressedBase85TTF(const char* compressed_ttf_data_base85, float size_pixels, const ImFontConfig* font_cfg, const ImWchar* glyph_ranges) ImFont* ImFontAtlas::AddFontFromMemoryCompressedBase85TTF(const char* compressed_ttf_data_base85, float size_pixels, const ImFontConfig* font_cfg, const ImWchar* glyph_ranges)
{ {
int compressed_ttf_size = (((int)strlen(compressed_ttf_data_base85) + 4) / 5) * 4; int compressed_ttf_size = (((int)strlen(compressed_ttf_data_base85) + 4) / 5) * 4;
void* compressed_ttf = ImGui::MemAlloc(compressed_ttf_size); void* compressed_ttf = ImGui::MemAlloc((size_t)compressed_ttf_size);
Decode85((const unsigned char*)compressed_ttf_data_base85, (unsigned char*)compressed_ttf); Decode85((const unsigned char*)compressed_ttf_data_base85, (unsigned char*)compressed_ttf);
ImFont* font = AddFontFromMemoryCompressedTTF(compressed_ttf, compressed_ttf_size, size_pixels, font_cfg, glyph_ranges); ImFont* font = AddFontFromMemoryCompressedTTF(compressed_ttf, compressed_ttf_size, size_pixels, font_cfg, glyph_ranges);
ImGui::MemFree(compressed_ttf); ImGui::MemFree(compressed_ttf);
@ -1223,8 +1284,9 @@ bool ImFontAtlas::Build()
} }
} }
// Start packing // Start packing. We need a known width for the skyline algorithm. Using a cheap heuristic here to decide of width. User can override TexDesiredWidth if they wish.
TexWidth = (TexDesiredWidth > 0) ? TexDesiredWidth : (total_glyph_count > 2000) ? 2048 : (total_glyph_count > 1000) ? 1024 : 512; // Width doesn't actually matters much but some API/GPU have texture size limitations, and increasing width can decrease height. // After packing is done, width shouldn't matter much, but some API/GPU have texture size limitations and increasing width can decrease height.
TexWidth = (TexDesiredWidth > 0) ? TexDesiredWidth : (total_glyph_count > 4000) ? 4096 : (total_glyph_count > 2000) ? 2048 : (total_glyph_count > 1000) ? 1024 : 512;
TexHeight = 0; TexHeight = 0;
const int max_tex_height = 1024*32; const int max_tex_height = 1024*32;
stbtt_pack_context spc; stbtt_pack_context spc;
@ -1605,7 +1667,7 @@ ImFont::~ImFont()
// If you want to delete fonts you need to do it between Render() and NewFrame(). // If you want to delete fonts you need to do it between Render() and NewFrame().
// FIXME-CLEANUP // FIXME-CLEANUP
/* /*
ImGuiState& g = *GImGui; ImGuiContext& g = *GImGui;
if (g.Font == this) if (g.Font == this)
g.Font = NULL; g.Font = NULL;
*/ */
@ -1633,20 +1695,15 @@ void ImFont::BuildLookupTable()
for (int i = 0; i != Glyphs.Size; i++) for (int i = 0; i != Glyphs.Size; i++)
max_codepoint = ImMax(max_codepoint, (int)Glyphs[i].Codepoint); max_codepoint = ImMax(max_codepoint, (int)Glyphs[i].Codepoint);
IM_ASSERT(Glyphs.Size < 32*1024);
IndexXAdvance.clear(); IndexXAdvance.clear();
IndexXAdvance.resize(max_codepoint + 1);
IndexLookup.clear(); IndexLookup.clear();
IndexLookup.resize(max_codepoint + 1); GrowIndex(max_codepoint + 1);
for (int i = 0; i < max_codepoint + 1; i++)
{
IndexXAdvance[i] = -1.0f;
IndexLookup[i] = -1;
}
for (int i = 0; i < Glyphs.Size; i++) for (int i = 0; i < Glyphs.Size; i++)
{ {
int codepoint = (int)Glyphs[i].Codepoint; int codepoint = (int)Glyphs[i].Codepoint;
IndexXAdvance[codepoint] = Glyphs[i].XAdvance; IndexXAdvance[codepoint] = Glyphs[i].XAdvance;
IndexLookup[codepoint] = i; IndexLookup[codepoint] = (short)i;
} }
// Create a glyph to handle TAB // Create a glyph to handle TAB
@ -1660,7 +1717,7 @@ void ImFont::BuildLookupTable()
tab_glyph.Codepoint = '\t'; tab_glyph.Codepoint = '\t';
tab_glyph.XAdvance *= 4; tab_glyph.XAdvance *= 4;
IndexXAdvance[(int)tab_glyph.Codepoint] = (float)tab_glyph.XAdvance; IndexXAdvance[(int)tab_glyph.Codepoint] = (float)tab_glyph.XAdvance;
IndexLookup[(int)tab_glyph.Codepoint] = (int)(Glyphs.Size-1); IndexLookup[(int)tab_glyph.Codepoint] = (short)(Glyphs.Size-1);
} }
FallbackGlyph = NULL; FallbackGlyph = NULL;
@ -1677,13 +1734,43 @@ void ImFont::SetFallbackChar(ImWchar c)
BuildLookupTable(); BuildLookupTable();
} }
void ImFont::GrowIndex(int new_size)
{
IM_ASSERT(IndexXAdvance.Size == IndexLookup.Size);
int old_size = IndexLookup.Size;
if (new_size <= old_size)
return;
IndexXAdvance.resize(new_size);
IndexLookup.resize(new_size);
for (int i = old_size; i < new_size; i++)
{
IndexXAdvance[i] = -1.0f;
IndexLookup[i] = (short)-1;
}
}
void ImFont::AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst)
{
IM_ASSERT(IndexLookup.Size > 0); // Currently this can only be called AFTER the font has been built, aka after calling ImFontAtlas::GetTexDataAs*() function.
int index_size = IndexLookup.Size;
if (dst < index_size && IndexLookup.Data[dst] == -1 && !overwrite_dst) // 'dst' already exists
return;
if (src >= index_size && dst >= index_size) // both 'dst' and 'src' don't exist -> no-op
return;
GrowIndex(dst + 1);
IndexLookup[dst] = (src < index_size) ? IndexLookup.Data[src] : -1;
IndexXAdvance[dst] = (src < index_size) ? IndexXAdvance.Data[src] : 1.0f;
}
const ImFont::Glyph* ImFont::FindGlyph(unsigned short c) const const ImFont::Glyph* ImFont::FindGlyph(unsigned short c) const
{ {
if (c < IndexLookup.Size) if (c < IndexLookup.Size)
{ {
const int i = IndexLookup[c]; const short i = IndexLookup[c];
if (i != -1) if (i != -1)
return &Glyphs[i]; return &Glyphs.Data[i];
} }
return FallbackGlyph; return FallbackGlyph;
} }
@ -1879,7 +1966,23 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
return text_size; return text_size;
} }
void ImFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, ImDrawList* draw_list, float wrap_width, bool cpu_fine_clip) const void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, unsigned short c) const
{
if (c == ' ' || c == '\t' || c == '\n' || c == '\r') // Match behavior of RenderText(), those 4 codepoints are hard-coded.
return;
if (const Glyph* glyph = FindGlyph(c))
{
float scale = (size >= 0.0f) ? (size / FontSize) : 1.0f;
pos.x = (float)(int)pos.x + DisplayOffset.x;
pos.y = (float)(int)pos.y + DisplayOffset.y;
ImVec2 pos_tl(pos.x + glyph->X0 * scale, pos.y + glyph->Y0 * scale);
ImVec2 pos_br(pos.x + glyph->X1 * scale, pos.y + glyph->Y1 * scale);
draw_list->PrimReserve(6, 4);
draw_list->PrimRectUV(pos_tl, pos_br, ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col);
}
}
void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip) const
{ {
if (!text_end) if (!text_end)
text_end = text_begin + strlen(text_begin); text_end = text_begin + strlen(text_begin);
@ -1897,14 +2000,22 @@ void ImFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_re
const bool word_wrap_enabled = (wrap_width > 0.0f); const bool word_wrap_enabled = (wrap_width > 0.0f);
const char* word_wrap_eol = NULL; const char* word_wrap_eol = NULL;
ImDrawVert* vtx_write = draw_list->_VtxWritePtr; // Skip non-visible lines
ImDrawIdx* idx_write = draw_list->_IdxWritePtr;
unsigned int vtx_current_idx = draw_list->_VtxCurrentIdx;
const char* s = text_begin; const char* s = text_begin;
if (!word_wrap_enabled && y + line_height < clip_rect.y) if (!word_wrap_enabled && y + line_height < clip_rect.y)
while (s < text_end && *s != '\n') // Fast-forward to next line while (s < text_end && *s != '\n') // Fast-forward to next line
s++; s++;
// Reserve vertices for remaining worse case (over-reserving is useful and easily amortized)
const int vtx_count_max = (int)(text_end - s) * 4;
const int idx_count_max = (int)(text_end - s) * 6;
const int idx_expected_size = draw_list->IdxBuffer.Size + idx_count_max;
draw_list->PrimReserve(idx_count_max, vtx_count_max);
ImDrawVert* vtx_write = draw_list->_VtxWritePtr;
ImDrawIdx* idx_write = draw_list->_IdxWritePtr;
unsigned int vtx_current_idx = draw_list->_VtxCurrentIdx;
while (s < text_end) while (s < text_end)
{ {
if (word_wrap_enabled) if (word_wrap_enabled)
@ -1969,15 +2080,14 @@ void ImFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_re
{ {
char_width = glyph->XAdvance * scale; char_width = glyph->XAdvance * scale;
// Clipping on Y is more likely // Arbitrarily assume that both space and tabs are empty glyphs as an optimization
if (c != ' ' && c != '\t') if (c != ' ' && c != '\t')
{ {
// We don't do a second finer clipping test on the Y axis (TODO: do some measurement see if it is worth it, probably not) // We don't do a second finer clipping test on the Y axis as we've already skipped anything before clip_rect.y and exit once we pass clip_rect.w
float y1 = (float)(y + glyph->Y0 * scale); float x1 = x + glyph->X0 * scale;
float y2 = (float)(y + glyph->Y1 * scale); float x2 = x + glyph->X1 * scale;
float y1 = y + glyph->Y0 * scale;
float x1 = (float)(x + glyph->X0 * scale); float y2 = y + glyph->Y1 * scale;
float x2 = (float)(x + glyph->X1 * scale);
if (x1 <= clip_rect.z && x2 >= clip_rect.x) if (x1 <= clip_rect.z && x2 >= clip_rect.x)
{ {
// Render a character // Render a character
@ -2016,8 +2126,8 @@ void ImFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_re
} }
} }
// NB: we are not calling PrimRectUV() here because non-inlined causes too much overhead in a debug build. // We are NOT calling PrimRectUV() here because non-inlined causes too much overhead in a debug build.
// inlined: // 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[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); idx_write[3] = (ImDrawIdx)(vtx_current_idx); idx_write[4] = (ImDrawIdx)(vtx_current_idx+2); idx_write[5] = (ImDrawIdx)(vtx_current_idx+3);
@ -2036,9 +2146,13 @@ void ImFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_re
x += char_width; x += char_width;
} }
// Give back unused vertices
draw_list->VtxBuffer.resize((int)(vtx_write - draw_list->VtxBuffer.Data));
draw_list->IdxBuffer.resize((int)(idx_write - draw_list->IdxBuffer.Data));
draw_list->CmdBuffer[draw_list->CmdBuffer.Size-1].ElemCount -= (idx_expected_size - draw_list->IdxBuffer.Size);
draw_list->_VtxWritePtr = vtx_write; draw_list->_VtxWritePtr = vtx_write;
draw_list->_VtxCurrentIdx = vtx_current_idx;
draw_list->_IdxWritePtr = idx_write; draw_list->_IdxWritePtr = idx_write;
draw_list->_VtxCurrentIdx = (unsigned int)draw_list->VtxBuffer.Size;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
// dear imgui, v1.47 // dear imgui, v1.49
// (internals) // (internals)
// You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility!
@ -19,6 +19,13 @@
#pragma warning (disable: 4251) // class 'xxx' needs to have dll-interface to be used by clients of struct 'xxx' // when IMGUI_API is set to__declspec(dllexport) #pragma warning (disable: 4251) // class 'xxx' needs to have dll-interface to be used by clients of struct 'xxx' // when IMGUI_API is set to__declspec(dllexport)
#endif #endif
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-function" // for stb_textedit.h
#pragma clang diagnostic ignored "-Wmissing-prototypes" // for stb_textedit.h
#pragma clang diagnostic ignored "-Wold-style-cast"
#endif
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Forward Declarations // Forward Declarations
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -33,7 +40,6 @@ struct ImGuiTextEditState;
struct ImGuiIniData; struct ImGuiIniData;
struct ImGuiMouseCursorData; struct ImGuiMouseCursorData;
struct ImGuiPopupRef; struct ImGuiPopupRef;
struct ImGuiState;
struct ImGuiWindow; struct ImGuiWindow;
typedef int ImGuiLayoutType; // enum ImGuiLayoutType_ typedef int ImGuiLayoutType; // enum ImGuiLayoutType_
@ -48,12 +54,6 @@ typedef int ImGuiSliderFlags; // enum ImGuiSliderFlags_
namespace ImGuiStb namespace ImGuiStb
{ {
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-function"
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#endif
#undef STB_TEXTEDIT_STRING #undef STB_TEXTEDIT_STRING
#undef STB_TEXTEDIT_CHARTYPE #undef STB_TEXTEDIT_CHARTYPE
#define STB_TEXTEDIT_STRING ImGuiTextEditState #define STB_TEXTEDIT_STRING ImGuiTextEditState
@ -61,17 +61,13 @@ namespace ImGuiStb
#define STB_TEXTEDIT_GETWIDTH_NEWLINE -1.0f #define STB_TEXTEDIT_GETWIDTH_NEWLINE -1.0f
#include "stb_textedit.h" #include "stb_textedit.h"
#ifdef __clang__
#pragma clang diagnostic pop
#endif
} // namespace ImGuiStb } // namespace ImGuiStb
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Context // Context
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
extern IMGUI_API ImGuiState* GImGui; extern IMGUI_API ImGuiContext* GImGui; // current implicit ImGui context pointer
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Helpers // Helpers
@ -135,7 +131,17 @@ static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t)
static inline float ImLengthSqr(const ImVec2& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y; } static inline float ImLengthSqr(const ImVec2& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y; }
static inline float ImLengthSqr(const ImVec4& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y + lhs.z*lhs.z + lhs.w*lhs.w; } static inline float ImLengthSqr(const ImVec4& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y + lhs.z*lhs.z + lhs.w*lhs.w; }
static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = lhs.x*lhs.x + lhs.y*lhs.y; if (d > 0.0f) return 1.0f / sqrtf(d); return fail_value; } static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = lhs.x*lhs.x + lhs.y*lhs.y; if (d > 0.0f) return 1.0f / sqrtf(d); return fail_value; }
static inline ImVec2 ImRound(ImVec2 v) { return ImVec2((float)(int)v.x, (float)(int)v.y); } static inline float ImFloor(float f) { return (float)(int)f; }
static inline ImVec2 ImFloor(ImVec2 v) { return ImVec2((float)(int)v.x, (float)(int)v.y); }
// We call C++ constructor on own allocated memory via the placement "new(ptr) Type()" syntax.
// Defining a custom placement new() with a dummy parameter allows us to bypass including <new> which on some platforms complains when user has disabled exceptions.
#ifdef IMGUI_DEFINE_PLACEMENT_NEW
struct ImPlacementNewDummy {};
inline void* operator new(size_t, ImPlacementNewDummy, void* ptr) { return ptr; }
inline void operator delete(void*, ImPlacementNewDummy, void*) {}
#define IM_PLACEMENT_NEW(_PTR) new(ImPlacementNewDummy(), _PTR)
#endif
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Types // Types
@ -143,34 +149,31 @@ static inline ImVec2 ImRound(ImVec2 v)
enum ImGuiButtonFlags_ enum ImGuiButtonFlags_
{ {
ImGuiButtonFlags_Repeat = 1 << 0, ImGuiButtonFlags_Repeat = 1 << 0, // hold to repeat
ImGuiButtonFlags_PressedOnClick = 1 << 1, // return pressed on click only (default requires click+release) ImGuiButtonFlags_PressedOnClickRelease = 1 << 1, // (default) return pressed on click+release on same item (default if no PressedOn** flag is set)
ImGuiButtonFlags_PressedOnRelease = 1 << 2, // return pressed on release only (default requires click+release) ImGuiButtonFlags_PressedOnClick = 1 << 2, // return pressed on click (default requires click+release)
ImGuiButtonFlags_FlattenChilds = 1 << 3, ImGuiButtonFlags_PressedOnRelease = 1 << 3, // return pressed on release (default requires click+release)
ImGuiButtonFlags_DontClosePopups = 1 << 4, ImGuiButtonFlags_PressedOnDoubleClick = 1 << 4, // return pressed on double-click (default requires click+release)
ImGuiButtonFlags_Disabled = 1 << 5, ImGuiButtonFlags_FlattenChilds = 1 << 5, // allow interaction even if a child window is overlapping
ImGuiButtonFlags_AlignTextBaseLine = 1 << 6, ImGuiButtonFlags_DontClosePopups = 1 << 6, // disable automatically closing parent popup on press
ImGuiButtonFlags_NoKeyModifiers = 1 << 7 ImGuiButtonFlags_Disabled = 1 << 7, // disable interaction
}; ImGuiButtonFlags_AlignTextBaseLine = 1 << 8, // vertically align button to match text baseline - ButtonEx() only
ImGuiButtonFlags_NoKeyModifiers = 1 << 9, // disable interaction if a key modifier is held
enum ImGuiTreeNodeFlags_ ImGuiButtonFlags_AllowOverlapMode = 1 << 10 // require previous frame HoveredId to either match id or be null before being usable
{
ImGuiTreeNodeFlags_DefaultOpen = 1 << 0,
ImGuiTreeNodeFlags_NoAutoExpandOnLog = 1 << 1
}; };
enum ImGuiSliderFlags_ enum ImGuiSliderFlags_
{ {
ImGuiSliderFlags_Vertical = 1 << 0, ImGuiSliderFlags_Vertical = 1 << 0
}; };
enum ImGuiSelectableFlagsPrivate_ enum ImGuiSelectableFlagsPrivate_
{ {
// NB: need to be in sync with last value of ImGuiSelectableFlags_ // NB: need to be in sync with last value of ImGuiSelectableFlags_
ImGuiSelectableFlags_Menu = 1 << 2, ImGuiSelectableFlags_Menu = 1 << 3,
ImGuiSelectableFlags_MenuItem = 1 << 3, ImGuiSelectableFlags_MenuItem = 1 << 4,
ImGuiSelectableFlags_Disabled = 1 << 4, ImGuiSelectableFlags_Disabled = 1 << 5,
ImGuiSelectableFlags_DrawFillAvailWidth = 1 << 5 ImGuiSelectableFlags_DrawFillAvailWidth = 1 << 6
}; };
// FIXME: this is in development, not exposed/functional as a generic feature yet. // FIXME: this is in development, not exposed/functional as a generic feature yet.
@ -221,7 +224,7 @@ struct IMGUI_API ImRect
void Expand(const ImVec2& amount) { Min.x -= amount.x; Min.y -= amount.y; Max.x += amount.x; Max.y += amount.y; } void Expand(const ImVec2& amount) { Min.x -= amount.x; Min.y -= amount.y; Max.x += amount.x; Max.y += amount.y; }
void Reduce(const ImVec2& amount) { Min.x += amount.x; Min.y += amount.y; Max.x -= amount.x; Max.y -= amount.y; } void Reduce(const ImVec2& amount) { Min.x += amount.x; Min.y += amount.y; Max.x -= amount.x; Max.y -= amount.y; }
void Clip(const ImRect& clip) { if (Min.x < clip.Min.x) Min.x = clip.Min.x; if (Min.y < clip.Min.y) Min.y = clip.Min.y; if (Max.x > clip.Max.x) Max.x = clip.Max.x; if (Max.y > clip.Max.y) Max.y = clip.Max.y; } void Clip(const ImRect& clip) { if (Min.x < clip.Min.x) Min.x = clip.Min.x; if (Min.y < clip.Min.y) Min.y = clip.Min.y; if (Max.x > clip.Max.x) Max.x = clip.Max.x; if (Max.y > clip.Max.y) Max.y = clip.Max.y; }
void Round() { Min.x = (float)(int)Min.x; Min.y = (float)(int)Min.y; Max.x = (float)(int)Max.x; Max.y = (float)(int)Max.y; } void Floor() { Min.x = (float)(int)Min.x; Min.y = (float)(int)Min.y; Max.x = (float)(int)Max.x; Max.y = (float)(int)Max.y; }
ImVec2 GetClosestPoint(ImVec2 p, bool on_edge) const ImVec2 GetClosestPoint(ImVec2 p, bool on_edge) const
{ {
if (!on_edge && Contains(p)) if (!on_edge && Contains(p))
@ -267,7 +270,7 @@ struct ImGuiColumnData
//float IndentX; //float IndentX;
}; };
// Simple column measurement currently used for MenuItem() only. This is very short-sighted for now and NOT a generic helper. // Simple column measurement currently used for MenuItem() only. This is very short-sighted/throw-away code and NOT a generic helper.
struct IMGUI_API ImGuiSimpleColumns struct IMGUI_API ImGuiSimpleColumns
{ {
int Count; int Count;
@ -338,7 +341,7 @@ struct ImGuiPopupRef
}; };
// Main state for ImGui // Main state for ImGui
struct ImGuiState struct ImGuiContext
{ {
bool Initialized; bool Initialized;
ImGuiIO IO; ImGuiIO IO;
@ -346,7 +349,7 @@ struct ImGuiState
ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back() ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back()
float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize() float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize()
float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Size of characters. float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Size of characters.
ImVec2 FontTexUvWhitePixel; // (Shortcut) == Font->TexUvForWhite ImVec2 FontTexUvWhitePixel; // (Shortcut) == Font->TexUvWhitePixel
float Time; float Time;
int FrameCount; int FrameCount;
@ -367,15 +370,16 @@ struct ImGuiState
bool ActiveIdIsAlive; bool ActiveIdIsAlive;
bool ActiveIdIsJustActivated; // Set at the time of activation for one frame bool ActiveIdIsJustActivated; // Set at the time of activation for one frame
bool ActiveIdAllowOverlap; // Set only by active widget bool ActiveIdAllowOverlap; // Set only by active widget
ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior)
ImGuiWindow* ActiveIdWindow; ImGuiWindow* ActiveIdWindow;
ImGuiWindow* MovedWindow; // Track the child window we clicked on to move a window. Pointer is only valid if ActiveID is the "#MOVE" identifier of a window. ImGuiWindow* MovedWindow; // Track the child window we clicked on to move a window.
ImGuiID MovedWindowMoveId; // == MovedWindow->RootWindow->MoveId
ImVector<ImGuiIniData> Settings; // .ini Settings ImVector<ImGuiIniData> Settings; // .ini Settings
float SettingsDirtyTimer; // Save .ini settinngs on disk when time reaches zero float SettingsDirtyTimer; // Save .ini Settings on disk when time reaches zero
int DisableHideTextAfterDoubleHash;
ImVector<ImGuiColMod> ColorModifiers; // Stack for PushStyleColor()/PopStyleColor() ImVector<ImGuiColMod> ColorModifiers; // Stack for PushStyleColor()/PopStyleColor()
ImVector<ImGuiStyleMod> StyleModifiers; // Stack for PushStyleVar()/PopStyleVar() ImVector<ImGuiStyleMod> StyleModifiers; // Stack for PushStyleVar()/PopStyleVar()
ImVector<ImFont*> FontStack; // Stack for PushFont()/PopFont() ImVector<ImFont*> FontStack; // Stack for PushFont()/PopFont()
ImVector<ImGuiPopupRef> OpenedPopupStack; // Which popups are open (persistent) ImVector<ImGuiPopupRef> OpenPopupStack; // Which popups are open (persistent)
ImVector<ImGuiPopupRef> CurrentPopupStack; // Which level of BeginPopup() we are in (reset every frame) ImVector<ImGuiPopupRef> CurrentPopupStack; // Which level of BeginPopup() we are in (reset every frame)
// Storage for SetNexWindow** and SetNextTreeNode*** functions // Storage for SetNexWindow** and SetNextTreeNode*** functions
@ -387,9 +391,13 @@ struct ImGuiState
ImGuiSetCond SetNextWindowSizeCond; ImGuiSetCond SetNextWindowSizeCond;
ImGuiSetCond SetNextWindowContentSizeCond; ImGuiSetCond SetNextWindowContentSizeCond;
ImGuiSetCond SetNextWindowCollapsedCond; ImGuiSetCond SetNextWindowCollapsedCond;
ImRect SetNextWindowSizeConstraintRect; // Valid if 'SetNextWindowSizeConstraint' is true
ImGuiSizeConstraintCallback SetNextWindowSizeConstraintCallback;
void* SetNextWindowSizeConstraintCallbackUserData;
bool SetNextWindowSizeConstraint;
bool SetNextWindowFocus; bool SetNextWindowFocus;
bool SetNextTreeNodeOpenedVal; bool SetNextTreeNodeOpenVal;
ImGuiSetCond SetNextTreeNodeOpenedCond; ImGuiSetCond SetNextTreeNodeOpenCond;
// Render // Render
ImDrawData RenderDrawData; // Main ImDrawData instance to pass render information to the user ImDrawData RenderDrawData; // Main ImDrawData instance to pass render information to the user
@ -404,7 +412,6 @@ struct ImGuiState
ImFont InputTextPasswordFont; ImFont InputTextPasswordFont;
ImGuiID ScalarAsInputTextId; // Temporary text input when CTRL+clicking on a slider, etc. ImGuiID ScalarAsInputTextId; // Temporary text input when CTRL+clicking on a slider, etc.
ImGuiStorage ColorEditModeStorage; // Store user selection of color edit mode ImGuiStorage ColorEditModeStorage; // Store user selection of color edit mode
ImVec2 ActiveClickDeltaToCenter;
float DragCurrentValue; // Currently dragged value, always float, not rounded by end-user precision settings float DragCurrentValue; // Currently dragged value, always float, not rounded by end-user precision settings
ImVec2 DragLastMouseDelta; ImVec2 DragLastMouseDelta;
float DragSpeedDefaultRatio; // If speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio float DragSpeedDefaultRatio; // If speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio
@ -426,11 +433,11 @@ struct ImGuiState
float FramerateSecPerFrame[120]; // calculate estimate of framerate for user float FramerateSecPerFrame[120]; // calculate estimate of framerate for user
int FramerateSecPerFrameIdx; int FramerateSecPerFrameIdx;
float FramerateSecPerFrameAccum; float FramerateSecPerFrameAccum;
bool CaptureMouseNextFrame; // explicit capture via CaptureInputs() sets those flags int CaptureMouseNextFrame; // explicit capture via CaptureInputs() sets those flags
bool CaptureKeyboardNextFrame; int CaptureKeyboardNextFrame;
char TempBuffer[1024*3+1]; // temporary text buffer char TempBuffer[1024*3+1]; // temporary text buffer
ImGuiState() ImGuiContext()
{ {
Initialized = false; Initialized = false;
Font = NULL; Font = NULL;
@ -452,23 +459,26 @@ struct ImGuiState
ActiveIdIsAlive = false; ActiveIdIsAlive = false;
ActiveIdIsJustActivated = false; ActiveIdIsJustActivated = false;
ActiveIdAllowOverlap = false; ActiveIdAllowOverlap = false;
ActiveIdClickOffset = ImVec2(-1,-1);
ActiveIdWindow = NULL; ActiveIdWindow = NULL;
MovedWindow = NULL; MovedWindow = NULL;
MovedWindowMoveId = 0;
SettingsDirtyTimer = 0.0f; SettingsDirtyTimer = 0.0f;
DisableHideTextAfterDoubleHash = 0;
SetNextWindowPosVal = ImVec2(0.0f, 0.0f); SetNextWindowPosVal = ImVec2(0.0f, 0.0f);
SetNextWindowSizeVal = ImVec2(0.0f, 0.0f); SetNextWindowSizeVal = ImVec2(0.0f, 0.0f);
SetNextWindowCollapsedVal = false; SetNextWindowCollapsedVal = false;
SetNextWindowPosCond = 0; SetNextWindowPosCond = 0;
SetNextWindowSizeCond = 0; SetNextWindowSizeCond = 0;
SetNextWindowContentSizeCond = 0;
SetNextWindowCollapsedCond = 0; SetNextWindowCollapsedCond = 0;
SetNextWindowFocus = false; SetNextWindowFocus = false;
SetNextTreeNodeOpenedVal = false; SetNextWindowSizeConstraintCallback = NULL;
SetNextTreeNodeOpenedCond = 0; SetNextWindowSizeConstraintCallbackUserData = NULL;
SetNextTreeNodeOpenVal = false;
SetNextTreeNodeOpenCond = 0;
ScalarAsInputTextId = 0; ScalarAsInputTextId = 0;
ActiveClickDeltaToCenter = ImVec2(0.0f, 0.0f);
DragCurrentValue = 0.0f; DragCurrentValue = 0.0f;
DragLastMouseDelta = ImVec2(0.0f, 0.0f); DragLastMouseDelta = ImVec2(0.0f, 0.0f);
DragSpeedDefaultRatio = 0.01f; DragSpeedDefaultRatio = 0.01f;
@ -482,6 +492,7 @@ struct ImGuiState
ModalWindowDarkeningRatio = 0.0f; ModalWindowDarkeningRatio = 0.0f;
OverlayDrawList._OwnerName = "##Overlay"; // Give it a name for debugging OverlayDrawList._OwnerName = "##Overlay"; // Give it a name for debugging
MouseCursor = ImGuiMouseCursor_Arrow; MouseCursor = ImGuiMouseCursor_Arrow;
memset(MouseCursorData, 0, sizeof(MouseCursorData));
LogEnabled = false; LogEnabled = false;
LogFile = NULL; LogFile = NULL;
@ -492,7 +503,8 @@ struct ImGuiState
memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame)); memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame));
FramerateSecPerFrameIdx = 0; FramerateSecPerFrameIdx = 0;
FramerateSecPerFrameAccum = 0.0f; FramerateSecPerFrameAccum = 0.0f;
CaptureMouseNextFrame = CaptureKeyboardNextFrame = false; CaptureMouseNextFrame = CaptureKeyboardNextFrame = -1;
memset(TempBuffer, 0, sizeof(TempBuffer));
} }
}; };
@ -583,21 +595,24 @@ struct IMGUI_API ImGuiDrawContext
struct IMGUI_API ImGuiWindow struct IMGUI_API ImGuiWindow
{ {
char* Name; char* Name;
ImGuiID ID; ImGuiID ID; // == ImHash(Name)
ImGuiWindowFlags Flags; ImGuiWindowFlags Flags; // See enum ImGuiWindowFlags_
int IndexWithinParent; // Order within immediate parent window, if we are a child window. Otherwise 0.
ImVec2 PosFloat; ImVec2 PosFloat;
ImVec2 Pos; // Position rounded-up to nearest pixel ImVec2 Pos; // Position rounded-up to nearest pixel
ImVec2 Size; // Current size (==SizeFull or collapsed title bar size) ImVec2 Size; // Current size (==SizeFull or collapsed title bar size)
ImVec2 SizeFull; // Size when non collapsed ImVec2 SizeFull; // Size when non collapsed
ImVec2 SizeContents; // Size of contents (== extents reach of the drawing cursor) from previous frame ImVec2 SizeContents; // Size of contents (== extents reach of the drawing cursor) from previous frame
ImVec2 SizeContentsExplicit; // Size of contents explicitly set by the user via SetNextWindowContentSize() ImVec2 SizeContentsExplicit; // Size of contents explicitly set by the user via SetNextWindowContentSize()
ImRect ContentsRegionRect; // Maximum visible content position in window coordinates. ~~ (SizeContentsExplicit ? SizeContentsExplicit : Size - ScrollbarSizes) - CursorStartPos, per axis
ImVec2 WindowPadding; // Window padding at the time of begin. We need to lock it, in particular manipulation of the ShowBorder would have an effect ImVec2 WindowPadding; // Window padding at the time of begin. We need to lock it, in particular manipulation of the ShowBorder would have an effect
ImGuiID MoveID; // == window->GetID("#MOVE") ImGuiID MoveID; // == window->GetID("#MOVE")
ImVec2 Scroll; ImVec2 Scroll;
ImVec2 ScrollTarget; // target scroll position. stored as cursor position with scrolling canceled out, so the highest point is always 0.0f. (FLT_MAX for no change) ImVec2 ScrollTarget; // target scroll position. stored as cursor position with scrolling canceled out, so the highest point is always 0.0f. (FLT_MAX for no change)
ImVec2 ScrollTargetCenterRatio; // 0.0f = scroll so that target position is at top, 0.5f = scroll so that target position is centered ImVec2 ScrollTargetCenterRatio; // 0.0f = scroll so that target position is at top, 0.5f = scroll so that target position is centered
bool ScrollbarX, ScrollbarY; bool ScrollbarX, ScrollbarY;
ImVec2 ScrollbarSizes; // ImVec2 ScrollbarSizes;
float BorderSize;
bool Active; // Set to true on Begin() bool Active; // Set to true on Begin()
bool WasActive; bool WasActive;
bool Accessed; // Set to true when any widget access the current window bool Accessed; // Set to true when any widget access the current window
@ -617,15 +632,16 @@ struct IMGUI_API ImGuiWindow
ImGuiDrawContext DC; // Temporary per-window data, reset at the beginning of the frame ImGuiDrawContext DC; // Temporary per-window data, reset at the beginning of the frame
ImVector<ImGuiID> IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack ImVector<ImGuiID> IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack
ImRect ClipRect; // = DrawList->clip_rect_stack.back(). Scissoring / clipping rectangle. x1, y1, x2, y2. ImRect ClipRect; // = DrawList->clip_rect_stack.back(). Scissoring / clipping rectangle. x1, y1, x2, y2.
ImRect ClippedWindowRect; // = ClipRect just after setup in Begin() ImRect WindowRectClipped; // = WindowRect just after setup in Begin(). == window->Rect() for root window.
int LastFrameActive; int LastFrameActive;
float ItemWidthDefault; float ItemWidthDefault;
ImGuiSimpleColumns MenuColumns; // Simplified columns storage for menu items ImGuiSimpleColumns MenuColumns; // Simplified columns storage for menu items
ImGuiStorage StateStorage; ImGuiStorage StateStorage;
float FontWindowScale; // Scale multiplier per-window float FontWindowScale; // Scale multiplier per-window
ImDrawList* DrawList; ImDrawList* DrawList;
ImGuiWindow* RootWindow; ImGuiWindow* RootWindow; // If we are a child window, this is pointing to the first non-child parent window. Else point to ourself.
ImGuiWindow* RootNonPopupWindow; ImGuiWindow* RootNonPopupWindow; // If we are a child window, this is pointing to the first non-child non-popup parent window. Else point to ourself.
ImGuiWindow* ParentWindow; // If we are a child window, this is pointing to our parent window. Else point to NULL.
// Focus // Focus
int FocusIdxAllCounter; // Start at -1 and increase as assigned via FocusItemRegister() int FocusIdxAllCounter; // Start at -1 and increase as assigned via FocusItemRegister()
@ -661,17 +677,18 @@ namespace ImGui
// If this ever crash because g.CurrentWindow is NULL it means that either // If this ever crash because g.CurrentWindow is NULL it means that either
// - ImGui::NewFrame() has never been called, which is illegal. // - ImGui::NewFrame() has never been called, which is illegal.
// - You are calling ImGui functions after ImGui::Render() and before the next ImGui::NewFrame(), which is also illegal. // - You are calling ImGui functions after ImGui::Render() and before the next ImGui::NewFrame(), which is also illegal.
inline ImGuiWindow* GetCurrentWindowRead() { ImGuiState& g = *GImGui; return g.CurrentWindow; } inline ImGuiWindow* GetCurrentWindowRead() { ImGuiContext& g = *GImGui; return g.CurrentWindow; }
inline ImGuiWindow* GetCurrentWindow() { ImGuiState& g = *GImGui; g.CurrentWindow->Accessed = true; return g.CurrentWindow; } inline ImGuiWindow* GetCurrentWindow() { ImGuiContext& g = *GImGui; g.CurrentWindow->Accessed = true; return g.CurrentWindow; }
IMGUI_API ImGuiWindow* GetParentWindow(); IMGUI_API ImGuiWindow* GetParentWindow();
IMGUI_API ImGuiWindow* FindWindowByName(const char* name);
IMGUI_API void FocusWindow(ImGuiWindow* window); IMGUI_API void FocusWindow(ImGuiWindow* window);
IMGUI_API void EndFrame(); // Ends the ImGui frame. Automatically called by Render()! you most likely don't need to ever call that yourself directly. If you don't need to render you can call EndFrame() but you'll have wasted CPU already. If you don't need to render, don't create any windows instead!
IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window); IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window);
IMGUI_API void SetHoveredID(ImGuiID id); IMGUI_API void SetHoveredID(ImGuiID id);
IMGUI_API void KeepAliveID(ImGuiID id); IMGUI_API void KeepAliveID(ImGuiID id);
IMGUI_API void EndFrame(); // Automatically called by Render()
IMGUI_API void ItemSize(const ImVec2& size, float text_offset_y = 0.0f); IMGUI_API void ItemSize(const ImVec2& size, float text_offset_y = 0.0f);
IMGUI_API void ItemSize(const ImRect& bb, float text_offset_y = 0.0f); IMGUI_API void ItemSize(const ImRect& bb, float text_offset_y = 0.0f);
IMGUI_API bool ItemAdd(const ImRect& bb, const ImGuiID* id); IMGUI_API bool ItemAdd(const ImRect& bb, const ImGuiID* id);
@ -681,7 +698,6 @@ namespace ImGui
IMGUI_API void FocusableItemUnregister(ImGuiWindow* window); IMGUI_API void FocusableItemUnregister(ImGuiWindow* window);
IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_x, float default_y); IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_x, float default_y);
IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x); IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x);
IMGUI_API void SetItemAllowOverlap(); // Allow last item to be overlapped by a subsequent item
IMGUI_API void OpenPopupEx(const char* str_id, bool reopen_existing); IMGUI_API void OpenPopupEx(const char* str_id, bool reopen_existing);
@ -689,19 +705,20 @@ namespace ImGui
inline IMGUI_API ImU32 GetColorU32(const ImVec4& col) { ImVec4 c = col; c.w *= GImGui->Style.Alpha; return ImGui::ColorConvertFloat4ToU32(c); } inline IMGUI_API ImU32 GetColorU32(const ImVec4& col) { ImVec4 c = col; c.w *= GImGui->Style.Alpha; return ImGui::ColorConvertFloat4ToU32(c); }
// NB: All position are in absolute pixels coordinates (not window coordinates) // NB: All position are in absolute pixels coordinates (not window coordinates)
// FIXME: Refactor all RenderText* functions into one. // FIXME: All those functions are a mess and needs to be refactored into something decent. Avoid use outside of imgui.cpp!
// We need: a sort of symbol library, preferably baked into font atlas when possible + decent text rendering helpers.
IMGUI_API void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true); IMGUI_API void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true);
IMGUI_API void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width); IMGUI_API void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width);
IMGUI_API void RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, ImGuiAlign align = ImGuiAlign_Default, const ImVec2* clip_min = NULL, const ImVec2* clip_max = NULL); IMGUI_API void RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, ImGuiAlign align = ImGuiAlign_Default, const ImVec2* clip_min = NULL, const ImVec2* clip_max = NULL);
IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f); IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f);
IMGUI_API void RenderCollapseTriangle(ImVec2 p_min, bool opened, float scale = 1.0f, bool shadow = false); IMGUI_API void RenderCollapseTriangle(ImVec2 pos, bool is_open, float scale = 1.0f, bool shadow = false);
IMGUI_API void RenderBullet(ImVec2 pos);
IMGUI_API void RenderCheckMark(ImVec2 pos, ImU32 col); IMGUI_API void RenderCheckMark(ImVec2 pos, ImU32 col);
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 PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_existing_clip_rect = true);
IMGUI_API void PopClipRect();
IMGUI_API bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0); IMGUI_API bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0);
IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0,0), ImGuiButtonFlags flags = 0); IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0,0), ImGuiButtonFlags flags = 0);
IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos, float radius);
IMGUI_API bool SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, ImGuiSliderFlags flags = 0); IMGUI_API bool SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, ImGuiSliderFlags flags = 0);
IMGUI_API bool SliderFloatN(const char* label, float* v, int components, float v_min, float v_max, const char* display_format, float power); IMGUI_API bool SliderFloatN(const char* label, float* v, int components, float v_min, float v_max, const char* display_format, float power);
@ -717,14 +734,20 @@ namespace ImGui
IMGUI_API bool InputScalarEx(const char* label, ImGuiDataType data_type, void* data_ptr, void* step_ptr, void* step_fast_ptr, const char* scalar_format, ImGuiInputTextFlags extra_flags); IMGUI_API bool InputScalarEx(const char* label, ImGuiDataType data_type, void* data_ptr, void* step_ptr, void* step_fast_ptr, const char* scalar_format, ImGuiInputTextFlags extra_flags);
IMGUI_API bool InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label, ImGuiDataType data_type, void* data_ptr, ImGuiID id, int decimal_precision); IMGUI_API bool InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label, ImGuiDataType data_type, void* data_ptr, ImGuiID id, int decimal_precision);
IMGUI_API bool TreeNodeBehaviorIsOpened(ImGuiID id, ImGuiTreeNodeFlags flags = 0); // Consume previous SetNextTreeNodeOpened() data, if any. May return true when logging IMGUI_API bool TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end = NULL);
IMGUI_API bool TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags = 0); // Consume previous SetNextTreeNodeOpened() data, if any. May return true when logging
IMGUI_API void TreePushRawID(ImGuiID id);
IMGUI_API void 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 graph_size); IMGUI_API void 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 graph_size);
IMGUI_API int ParseFormatPrecision(const char* fmt, int default_value); IMGUI_API int ParseFormatPrecision(const char* fmt, int default_value);
IMGUI_API float RoundScalar(float value, int decimal_precision); IMGUI_API float RoundScalar(float value, int decimal_precision);
} // namespace ImGuiP } // namespace ImGui
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning (pop) #pragma warning (pop)

View File

@ -268,9 +268,9 @@ STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height,
} }
// find minimum y position if it starts at x1 // find minimum y position if it starts at x1
static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste) static int stbrp__skyline_find_min_y(stbrp_context *, stbrp_node *first, int x0, int width, int *pwaste)
{ {
(void)c; //(void)c;
stbrp_node *node = first; stbrp_node *node = first;
int x1 = x0 + width; int x1 = x0 + width;
int min_y, visited_width, waste_area; int min_y, visited_width, waste_area;

View File

@ -1,8 +1,8 @@
// [ImGui] this is a slightly modified version of stb_truetype.h 1.4 // [ImGui] this is a slightly modified version of stb_truetype.h 1.8
// [ImGui] we made a fix for using the END key on multi-line text edit, see https://github.com/ocornut/imgui/issues/275 // [ImGui] - fixed some minor warnings
// [ImGui] we made a fix for using keyboard while using mouse, see https://github.com/nothings/stb/pull/209 // [ImGui] - added STB_TEXTEDIT_MOVEWORDLEFT/STB_TEXTEDIT_MOVEWORDRIGHT custom handler (#473)
// stb_textedit.h - v1.4 - public domain - Sean Barrett // stb_textedit.h - v1.8 - public domain - Sean Barrett
// Development of this library was sponsored by RAD Game Tools // Development of this library was sponsored by RAD Game Tools
// //
// This C header file implements the guts of a multi-line text-editing // This C header file implements the guts of a multi-line text-editing
@ -21,19 +21,24 @@
// //
// LICENSE // LICENSE
// //
// This software has been placed in the public domain by its author. // This software is dual-licensed to the public domain and under the following
// Where that dedication is not recognized, you are granted a perpetual, // license: you are granted a perpetual, irrevocable license to copy, modify,
// irrevocable license to copy and modify this file as you see fit. // publish, and distribute this file as you see fit.
// //
// //
// DEPENDENCIES // DEPENDENCIES
// //
// Uses the C runtime function 'memmove'. Uses no other functions. // Uses the C runtime function 'memmove', which you can override
// Performs no runtime allocations. // by defining STB_TEXTEDIT_memmove before the implementation.
// Uses no other functions. Performs no runtime allocations.
// //
// //
// VERSION HISTORY // VERSION HISTORY
// //
// 1.8 (2016-04-02) better keyboard handling when mouse button is down
// 1.7 (2015-09-13) change y range handling in case baseline is non-0
// 1.6 (2015-04-15) allow STB_TEXTEDIT_memmove
// 1.5 (2014-09-10) add support for secondary keys for OS X
// 1.4 (2014-08-17) fix signed/unsigned warnings // 1.4 (2014-08-17) fix signed/unsigned warnings
// 1.3 (2014-06-19) fix mouse clicking to round to nearest char boundary // 1.3 (2014-06-19) fix mouse clicking to round to nearest char boundary
// 1.2 (2014-05-27) fix some RAD types that had crept into the new code // 1.2 (2014-05-27) fix some RAD types that had crept into the new code
@ -46,7 +51,13 @@
// ADDITIONAL CONTRIBUTORS // ADDITIONAL CONTRIBUTORS
// //
// Ulf Winklemann: move-by-word in 1.1 // Ulf Winklemann: move-by-word in 1.1
// Scott Graham: mouse selection bugfix in 1.3 // Fabian Giesen: secondary key inputs in 1.5
// Martins Mozeiko: STB_TEXTEDIT_memmove
//
// Bugfixes:
// Scott Graham
// Daniel Keller
// Omar Cornut
// //
// USAGE // USAGE
// //
@ -143,9 +154,15 @@
// Optional: // Optional:
// STB_TEXTEDIT_K_INSERT keyboard input to toggle insert mode // STB_TEXTEDIT_K_INSERT keyboard input to toggle insert mode
// STB_TEXTEDIT_IS_SPACE(ch) true if character is whitespace (e.g. 'isspace'), // STB_TEXTEDIT_IS_SPACE(ch) true if character is whitespace (e.g. 'isspace'),
// required for WORDLEFT/WORDRIGHT // required for default WORDLEFT/WORDRIGHT handlers
// STB_TEXTEDIT_MOVEWORDLEFT(obj,i) custom handler for WORDLEFT, returns index to move cursor to
// STB_TEXTEDIT_MOVEWORDRIGHT(obj,i) custom handler for WORDRIGHT, returns index to move cursor to
// STB_TEXTEDIT_K_WORDLEFT keyboard input to move cursor left one word // e.g. ctrl-LEFT // STB_TEXTEDIT_K_WORDLEFT keyboard input to move cursor left one word // e.g. ctrl-LEFT
// STB_TEXTEDIT_K_WORDRIGHT keyboard input to move cursor right one word // e.g. ctrl-RIGHT // STB_TEXTEDIT_K_WORDRIGHT keyboard input to move cursor right one word // e.g. ctrl-RIGHT
// STB_TEXTEDIT_K_LINESTART2 secondary keyboard input to move cursor to start of line
// STB_TEXTEDIT_K_LINEEND2 secondary keyboard input to move cursor to end of line
// STB_TEXTEDIT_K_TEXTSTART2 secondary keyboard input to move cursor to start of text
// STB_TEXTEDIT_K_TEXTEND2 secondary keyboard input to move cursor to end of text
// //
// Todo: // Todo:
// STB_TEXTEDIT_K_PGUP keyboard input to move cursor up a page // STB_TEXTEDIT_K_PGUP keyboard input to move cursor up a page
@ -356,7 +373,10 @@ typedef struct
// included just the "header" portion // included just the "header" portion
#ifdef STB_TEXTEDIT_IMPLEMENTATION #ifdef STB_TEXTEDIT_IMPLEMENTATION
#include <string.h> // memmove #ifndef STB_TEXTEDIT_memmove
#include <string.h>
#define STB_TEXTEDIT_memmove memmove
#endif
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -372,9 +392,6 @@ static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y)
float base_y = 0, prev_x; float base_y = 0, prev_x;
int i=0, k; int i=0, k;
if (y < 0)
return 0;
r.x0 = r.x1 = 0; r.x0 = r.x1 = 0;
r.ymin = r.ymax = 0; r.ymin = r.ymax = 0;
r.num_chars = 0; r.num_chars = 0;
@ -385,6 +402,9 @@ static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y)
if (r.num_chars <= 0) if (r.num_chars <= 0)
return n; return n;
if (i==0 && y < base_y + r.ymin)
return 0;
if (y < base_y + r.ymax) if (y < base_y + r.ymax)
break; break;
@ -601,9 +621,9 @@ static int is_word_boundary( STB_TEXTEDIT_STRING *_str, int _idx )
return _idx > 0 ? (STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(_str,_idx-1) ) && !STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(_str, _idx) ) ) : 1; return _idx > 0 ? (STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(_str,_idx-1) ) && !STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(_str, _idx) ) ) : 1;
} }
static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *_str, STB_TexteditState *_state ) #ifndef STB_TEXTEDIT_MOVEWORDLEFT
static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *_str, int c )
{ {
int c = _state->cursor - 1;
while( c >= 0 && !is_word_boundary( _str, c ) ) while( c >= 0 && !is_word_boundary( _str, c ) )
--c; --c;
@ -612,11 +632,13 @@ static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *_str, STB_Te
return c; return c;
} }
#define STB_TEXTEDIT_MOVEWORDLEFT stb_textedit_move_to_word_previous
#endif
static int stb_textedit_move_to_word_next( STB_TEXTEDIT_STRING *_str, STB_TexteditState *_state ) #ifndef STB_TEXTEDIT_MOVEWORDRIGHT
static int stb_textedit_move_to_word_next( STB_TEXTEDIT_STRING *_str, int c )
{ {
const int len = STB_TEXTEDIT_STRINGLEN(_str); const int len = STB_TEXTEDIT_STRINGLEN(_str);
int c = _state->cursor+1;
while( c < len && !is_word_boundary( _str, c ) ) while( c < len && !is_word_boundary( _str, c ) )
++c; ++c;
@ -625,6 +647,9 @@ static int stb_textedit_move_to_word_next( STB_TEXTEDIT_STRING *_str, STB_Texted
return c; return c;
} }
#define STB_TEXTEDIT_MOVEWORDRIGHT stb_textedit_move_to_word_next
#endif
#endif #endif
// update selection and cursor to match each other // update selection and cursor to match each other
@ -746,21 +771,12 @@ retry:
state->has_preferred_x = 0; state->has_preferred_x = 0;
break; break;
#ifdef STB_TEXTEDIT_IS_SPACE #ifdef STB_TEXTEDIT_MOVEWORDLEFT
case STB_TEXTEDIT_K_WORDLEFT: case STB_TEXTEDIT_K_WORDLEFT:
if (STB_TEXT_HAS_SELECTION(state)) if (STB_TEXT_HAS_SELECTION(state))
stb_textedit_move_to_first(state); stb_textedit_move_to_first(state);
else { else {
state->cursor = stb_textedit_move_to_word_previous(str, state); state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor-1);
stb_textedit_clamp( str, state );
}
break;
case STB_TEXTEDIT_K_WORDRIGHT:
if (STB_TEXT_HAS_SELECTION(state))
stb_textedit_move_to_last(str, state);
else {
state->cursor = stb_textedit_move_to_word_next(str, state);
stb_textedit_clamp( str, state ); stb_textedit_clamp( str, state );
} }
break; break;
@ -769,17 +785,28 @@ retry:
if( !STB_TEXT_HAS_SELECTION( state ) ) if( !STB_TEXT_HAS_SELECTION( state ) )
stb_textedit_prep_selection_at_cursor(state); stb_textedit_prep_selection_at_cursor(state);
state->cursor = stb_textedit_move_to_word_previous(str, state); state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor-1);
state->select_end = state->cursor; state->select_end = state->cursor;
stb_textedit_clamp( str, state ); stb_textedit_clamp( str, state );
break; break;
#endif
#ifdef STB_TEXTEDIT_MOVEWORDRIGHT
case STB_TEXTEDIT_K_WORDRIGHT:
if (STB_TEXT_HAS_SELECTION(state))
stb_textedit_move_to_last(str, state);
else {
state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor+1);
stb_textedit_clamp( str, state );
}
break;
case STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT: case STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT:
if( !STB_TEXT_HAS_SELECTION( state ) ) if( !STB_TEXT_HAS_SELECTION( state ) )
stb_textedit_prep_selection_at_cursor(state); stb_textedit_prep_selection_at_cursor(state);
state->cursor = stb_textedit_move_to_word_next(str, state); state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor+1);
state->select_end = state->cursor; state->select_end = state->cursor;
stb_textedit_clamp( str, state ); stb_textedit_clamp( str, state );
@ -923,23 +950,35 @@ retry:
state->has_preferred_x = 0; state->has_preferred_x = 0;
break; break;
#ifdef STB_TEXTEDIT_K_TEXTSTART2
case STB_TEXTEDIT_K_TEXTSTART2:
#endif
case STB_TEXTEDIT_K_TEXTSTART: case STB_TEXTEDIT_K_TEXTSTART:
state->cursor = state->select_start = state->select_end = 0; state->cursor = state->select_start = state->select_end = 0;
state->has_preferred_x = 0; state->has_preferred_x = 0;
break; break;
#ifdef STB_TEXTEDIT_K_TEXTEND2
case STB_TEXTEDIT_K_TEXTEND2:
#endif
case STB_TEXTEDIT_K_TEXTEND: case STB_TEXTEDIT_K_TEXTEND:
state->cursor = STB_TEXTEDIT_STRINGLEN(str); state->cursor = STB_TEXTEDIT_STRINGLEN(str);
state->select_start = state->select_end = 0; state->select_start = state->select_end = 0;
state->has_preferred_x = 0; state->has_preferred_x = 0;
break; break;
#ifdef STB_TEXTEDIT_K_TEXTSTART2
case STB_TEXTEDIT_K_TEXTSTART2 | STB_TEXTEDIT_K_SHIFT:
#endif
case STB_TEXTEDIT_K_TEXTSTART | STB_TEXTEDIT_K_SHIFT: case STB_TEXTEDIT_K_TEXTSTART | STB_TEXTEDIT_K_SHIFT:
stb_textedit_prep_selection_at_cursor(state); stb_textedit_prep_selection_at_cursor(state);
state->cursor = state->select_end = 0; state->cursor = state->select_end = 0;
state->has_preferred_x = 0; state->has_preferred_x = 0;
break; break;
#ifdef STB_TEXTEDIT_K_TEXTEND2
case STB_TEXTEDIT_K_TEXTEND2 | STB_TEXTEDIT_K_SHIFT:
#endif
case STB_TEXTEDIT_K_TEXTEND | STB_TEXTEDIT_K_SHIFT: case STB_TEXTEDIT_K_TEXTEND | STB_TEXTEDIT_K_SHIFT:
stb_textedit_prep_selection_at_cursor(state); stb_textedit_prep_selection_at_cursor(state);
state->cursor = state->select_end = STB_TEXTEDIT_STRINGLEN(str); state->cursor = state->select_end = STB_TEXTEDIT_STRINGLEN(str);
@ -947,6 +986,9 @@ retry:
break; break;
#ifdef STB_TEXTEDIT_K_LINESTART2
case STB_TEXTEDIT_K_LINESTART2:
#endif
case STB_TEXTEDIT_K_LINESTART: { case STB_TEXTEDIT_K_LINESTART: {
StbFindState find; StbFindState find;
stb_textedit_clamp(str, state); stb_textedit_clamp(str, state);
@ -957,18 +999,25 @@ retry:
break; break;
} }
#ifdef STB_TEXTEDIT_K_LINEEND2
case STB_TEXTEDIT_K_LINEEND2:
#endif
case STB_TEXTEDIT_K_LINEEND: { case STB_TEXTEDIT_K_LINEEND: {
StbFindState find; StbFindState find;
stb_textedit_clamp(str, state); stb_textedit_clamp(str, state);
stb_textedit_move_to_first(state); stb_textedit_move_to_first(state);
stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
state->has_preferred_x = 0;
state->cursor = find.first_char + find.length; state->cursor = find.first_char + find.length;
if (find.length > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) == STB_TEXTEDIT_NEWLINE) if (find.length > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) == STB_TEXTEDIT_NEWLINE)
state->cursor--; --state->cursor;
state->has_preferred_x = 0;
break; break;
} }
#ifdef STB_TEXTEDIT_K_LINESTART2
case STB_TEXTEDIT_K_LINESTART2 | STB_TEXTEDIT_K_SHIFT:
#endif
case STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_K_SHIFT: { case STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_K_SHIFT: {
StbFindState find; StbFindState find;
stb_textedit_clamp(str, state); stb_textedit_clamp(str, state);
@ -979,15 +1028,19 @@ retry:
break; break;
} }
#ifdef STB_TEXTEDIT_K_LINEEND2
case STB_TEXTEDIT_K_LINEEND2 | STB_TEXTEDIT_K_SHIFT:
#endif
case STB_TEXTEDIT_K_LINEEND | STB_TEXTEDIT_K_SHIFT: { case STB_TEXTEDIT_K_LINEEND | STB_TEXTEDIT_K_SHIFT: {
StbFindState find; StbFindState find;
stb_textedit_clamp(str, state); stb_textedit_clamp(str, state);
stb_textedit_prep_selection_at_cursor(state); stb_textedit_prep_selection_at_cursor(state);
stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
state->cursor = state->select_end = find.first_char + find.length;
if (find.length > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) == STB_TEXTEDIT_NEWLINE)
state->cursor = state->select_end = state->cursor - 1;
state->has_preferred_x = 0; state->has_preferred_x = 0;
state->cursor = find.first_char + find.length;
if (find.length > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) == STB_TEXTEDIT_NEWLINE)
--state->cursor;
state->select_end = state->cursor;
break; break;
} }
@ -1018,13 +1071,13 @@ static void stb_textedit_discard_undo(StbUndoState *state)
int n = state->undo_rec[0].insert_length, i; int n = state->undo_rec[0].insert_length, i;
// delete n characters from all other records // delete n characters from all other records
state->undo_char_point = state->undo_char_point - (short) n; // vsnet05 state->undo_char_point = state->undo_char_point - (short) n; // vsnet05
memmove(state->undo_char, state->undo_char + n, (size_t) ((size_t)state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE))); STB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t) ((size_t)state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE)));
for (i=0; i < state->undo_point; ++i) for (i=0; i < state->undo_point; ++i)
if (state->undo_rec[i].char_storage >= 0) if (state->undo_rec[i].char_storage >= 0)
state->undo_rec[i].char_storage = state->undo_rec[i].char_storage - (short) n; // vsnet05 // @OPTIMIZE: get rid of char_storage and infer it state->undo_rec[i].char_storage = state->undo_rec[i].char_storage - (short) n; // vsnet05 // @OPTIMIZE: get rid of char_storage and infer it
} }
--state->undo_point; --state->undo_point;
memmove(state->undo_rec, state->undo_rec+1, (size_t) ((size_t)state->undo_point*sizeof(state->undo_rec[0]))); STB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (size_t) ((size_t)state->undo_point*sizeof(state->undo_rec[0])));
} }
} }
@ -1042,13 +1095,13 @@ static void stb_textedit_discard_redo(StbUndoState *state)
int n = state->undo_rec[k].insert_length, i; int n = state->undo_rec[k].insert_length, i;
// delete n characters from all other records // delete n characters from all other records
state->redo_char_point = state->redo_char_point + (short) n; // vsnet05 state->redo_char_point = state->redo_char_point + (short) n; // vsnet05
memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((size_t)(STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE))); STB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((size_t)(STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE)));
for (i=state->redo_point; i < k; ++i) for (i=state->redo_point; i < k; ++i)
if (state->undo_rec[i].char_storage >= 0) if (state->undo_rec[i].char_storage >= 0)
state->undo_rec[i].char_storage = state->undo_rec[i].char_storage + (short) n; // vsnet05 state->undo_rec[i].char_storage = state->undo_rec[i].char_storage + (short) n; // vsnet05
} }
++state->redo_point; ++state->redo_point;
memmove(state->undo_rec + state->redo_point-1, state->undo_rec + state->redo_point, (size_t) ((size_t)(STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0]))); STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point-1, state->undo_rec + state->redo_point, (size_t) ((size_t)(STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0])));
} }
} }

View File

@ -1,4 +1,4 @@
// stb_truetype.h - v1.08 - public domain // stb_truetype.h - v1.10 - public domain
// authored from 2009-2015 by Sean Barrett / RAD Game Tools // authored from 2009-2015 by Sean Barrett / RAD Game Tools
// //
// This library processes TrueType files: // This library processes TrueType files:
@ -21,6 +21,10 @@
// Mikko Mononen: compound shape support, more cmap formats // Mikko Mononen: compound shape support, more cmap formats
// Tor Andersson: kerning, subpixel rendering // Tor Andersson: kerning, subpixel rendering
// //
// Misc other:
// Ryan Gordon
// Simon Glass
//
// Bug/warning reports/fixes: // Bug/warning reports/fixes:
// "Zer" on mollyrocket (with fix) // "Zer" on mollyrocket (with fix)
// Cass Everitt // Cass Everitt
@ -42,12 +46,13 @@
// Sergey Popov // Sergey Popov
// Giumo X. Clanjor // Giumo X. Clanjor
// Higor Euripedes // Higor Euripedes
// // Thomas Fields
// Misc other: // Derek Vinyard
// Ryan Gordon
// //
// VERSION HISTORY // VERSION HISTORY
// //
// 1.10 (2016-04-02) user-defined fabs(); rare memory leak; remove duplicate typedef
// 1.09 (2016-01-16) warning fix; avoid crash on outofmem; use allocation userdata properly
// 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges // 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges
// 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints; // 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints;
// variant PackFontRanges to pack and render in separate phases; // variant PackFontRanges to pack and render in separate phases;
@ -65,9 +70,9 @@
// //
// LICENSE // LICENSE
// //
// This software is in the public domain. Where that dedication is not // This software is dual-licensed to the public domain and under the following
// recognized, you are granted a perpetual, irrevocable license to copy, // license: you are granted a perpetual, irrevocable license to copy, modify,
// distribute, and modify this file as you see fit. // publish, and distribute this file as you see fit.
// //
// USAGE // USAGE
// //
@ -403,6 +408,11 @@ int main(int arg, char **argv)
#define STBTT_sqrt(x) sqrt(x) #define STBTT_sqrt(x) sqrt(x)
#endif #endif
#ifndef STBTT_fabs
#include <math.h>
#define STBTT_fabs(x) fabs(x)
#endif
// #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h // #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h
#ifndef STBTT_malloc #ifndef STBTT_malloc
#include <stdlib.h> #include <stdlib.h>
@ -626,7 +636,7 @@ STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index);
// The following structure is defined publically so you can declare one on // The following structure is defined publically so you can declare one on
// the stack or as a global or etc, but you should treat it as opaque. // the stack or as a global or etc, but you should treat it as opaque.
typedef struct stbtt_fontinfo struct stbtt_fontinfo
{ {
void * userdata; void * userdata;
unsigned char * data; // pointer to .ttf file unsigned char * data; // pointer to .ttf file
@ -637,7 +647,7 @@ typedef struct stbtt_fontinfo
int loca,head,glyf,hhea,hmtx,kern; // table locations as offset from start of .ttf int loca,head,glyf,hhea,hmtx,kern; // table locations as offset from start of .ttf
int index_map; // a cmap mapping for our chosen character encoding int index_map; // a cmap mapping for our chosen character encoding
int indexToLocFormat; // format needed to map from glyph index to glyph int indexToLocFormat; // format needed to map from glyph index to glyph
} stbtt_fontinfo; };
STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset); STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset);
// Given an offset into the file that defines a font, this function builds // Given an offset into the file that defines a font, this function builds
@ -1556,7 +1566,7 @@ STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v)
STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1)
{ {
int x0,y0,x1,y1; int x0=0,y0=0,x1,y1; // =0 suppresses compiler warning
if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) { if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) {
// e.g. space character // e.g. space character
if (ix0) *ix0 = 0; if (ix0) *ix0 = 0;
@ -1672,6 +1682,7 @@ static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, i
{ {
stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata); stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata);
float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
STBTT_assert(z != NULL);
if (!z) return z; if (!z) return z;
// round dx down to avoid overshooting // round dx down to avoid overshooting
@ -1693,6 +1704,7 @@ static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, i
{ {
stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata); stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata);
float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
STBTT_assert(z != NULL);
//STBTT_assert(e->y0 <= start_point); //STBTT_assert(e->y0 <= start_point);
if (!z) return z; if (!z) return z;
z->fdx = dxdy; z->fdx = dxdy;
@ -1817,6 +1829,7 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
while (e->y0 <= scan_y) { while (e->y0 <= scan_y) {
if (e->y1 > scan_y) { if (e->y1 > scan_y) {
stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y, userdata); stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y, userdata);
if (z != NULL) {
// find insertion point // find insertion point
if (active == NULL) if (active == NULL)
active = z; active = z;
@ -1834,6 +1847,7 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
p->next = z; p->next = z;
} }
} }
}
++e; ++e;
} }
@ -1986,7 +2000,7 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
} }
y_crossing += dy * (x2 - (x1+1)); y_crossing += dy * (x2 - (x1+1));
STBTT_assert(fabs(area) <= 1.01f); STBTT_assert(STBTT_fabs(area) <= 1.01f);
scanline[x2] += area + sign * (1-((x2-x2)+(x_bottom-x2))/2) * (sy1-y_crossing); scanline[x2] += area + sign * (1-((x2-x2)+(x_bottom-x2))/2) * (sy1-y_crossing);
@ -2102,11 +2116,13 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
while (e->y0 <= scan_y_bottom) { while (e->y0 <= scan_y_bottom) {
if (e->y0 != e->y1) { if (e->y0 != e->y1) {
stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata); stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata);
if (z != NULL) {
STBTT_assert(z->ey >= scan_y_top); STBTT_assert(z->ey >= scan_y_top);
// insert at front // insert at front
z->next = active; z->next = active;
active = z; active = z;
} }
}
++e; ++e;
} }
@ -2121,7 +2137,7 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
int m; int m;
sum += scanline2[i]; sum += scanline2[i];
k = scanline[i] + sum; k = scanline[i] + sum;
k = (float) fabs(k)*255 + 0.5f; k = (float) STBTT_fabs(k)*255 + 0.5f;
m = (int) k; m = (int) k;
if (m > 255) m = 255; if (m > 255) m = 255;
result->pixels[j*result->stride + i] = (unsigned char) m; result->pixels[j*result->stride + i] = (unsigned char) m;
@ -2422,7 +2438,10 @@ STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info
if (scale_x == 0) scale_x = scale_y; if (scale_x == 0) scale_x = scale_y;
if (scale_y == 0) { if (scale_y == 0) {
if (scale_x == 0) return NULL; if (scale_x == 0) {
STBTT_free(vertices, info->userdata);
return NULL;
}
scale_y = scale_x; scale_y = scale_x;
} }
@ -2514,6 +2533,7 @@ STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // fo
float scale; float scale;
int x,y,bottom_y, i; int x,y,bottom_y, i;
stbtt_fontinfo f; stbtt_fontinfo f;
f.userdata = NULL;
if (!stbtt_InitFont(&f, data, offset)) if (!stbtt_InitFont(&f, data, offset))
return -1; return -1;
STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels
@ -2707,6 +2727,7 @@ static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_i
unsigned char buffer[STBTT_MAX_OVERSAMPLE]; unsigned char buffer[STBTT_MAX_OVERSAMPLE];
int safe_w = w - kernel_width; int safe_w = w - kernel_width;
int j; int j;
STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze
for (j=0; j < h; ++j) { for (j=0; j < h; ++j) {
int i; int i;
unsigned int total; unsigned int total;
@ -2768,6 +2789,7 @@ static void stbtt__v_prefilter(unsigned char *pixels, int w, int h, int stride_i
unsigned char buffer[STBTT_MAX_OVERSAMPLE]; unsigned char buffer[STBTT_MAX_OVERSAMPLE];
int safe_h = h - kernel_width; int safe_h = h - kernel_width;
int j; int j;
STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze
for (j=0; j < w; ++j) { for (j=0; j < w; ++j) {
int i; int i;
unsigned int total; unsigned int total;
@ -2976,6 +2998,7 @@ STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontd
if (rects == NULL) if (rects == NULL)
return 0; return 0;
info.userdata = spc->user_allocator_context;
stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata,font_index)); stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata,font_index));
n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects); n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects);
@ -3193,6 +3216,10 @@ STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *font_collection, const
// FULL VERSION HISTORY // FULL VERSION HISTORY
// //
// 1.10 (2016-04-02) allow user-defined fabs() replacement
// fix memory leak if fontsize=0.0
// fix warning from duplicate typedef
// 1.09 (2016-01-16) warning fix; avoid crash on outofmem; use alloc userdata for PackFontRanges
// 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges // 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges
// 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints; // 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints;
// allow PackFontRanges to pack and render in separate phases; // allow PackFontRanges to pack and render in separate phases;