Compare commits

..

400 Commits
v1.67 ... v1.71

Author SHA1 Message Date
2da1c66d15 Version 1.71 + comments 2019-06-12 18:30:06 +02:00
5ae268c0a3 Internals: Reworked RenderTextEllipsis() to satisfy what we need for table headers. 2019-06-11 16:12:00 +02:00
4597632662 Readme, comments, dear imgui prefixes 2019-06-11 16:11:36 +02:00
c3a348aa25 CollapsingHeader: Minor fix to align right side of frames (which is extruded past the Work/Contents rect) with clipping rectangle. 2019-06-11 15:56:57 +02:00
a8eb64fc54 Log/Capture: Fixed BeginTabItem() label not being included in a text log/capture.
Extracted tab rendering code into a RenderTextEllipsis() function.
2019-06-11 14:03:13 +02:00
a9b5c834b6 ImDrawListSplitter: Don't merge draw commands when crossing a VtxOffset boundary + Renamed fields ImDrawChannels to consistently suggest those are internal structures. 2019-06-11 11:49:31 +02:00
d8435c7710 ImDrawListSplitter: Fix idx offset when merging (cef88f6) (#2591) 2019-06-10 15:02:44 +02:00
0770449630 Window: child windows outer decorations (e.g. scrollbar) are rendered as part of their parent window, avoiding the creation of an extraneous draw command.
+ Metrics: inverted color of clip rect vs vertices bounding box when hovering a draw command, so the color matches the per-vertex preview.
2019-06-07 17:34:36 +02:00
afa3978ff6 Internals: Added drawlist and color arg to RenderArrow(), RenderBullet(). Reordered args for RenderPixelEllipsis. 2019-06-07 17:32:51 +02:00
32ab0a82d6 imgui-test: Added IMGUI_TEST_ENGINE_LOG macro to emit into test log from core or user land. 2019-06-07 13:46:54 +02:00
2b997141cf Made PushID() behave the same in 32-bit and 64-bit, by not padding the integer into a void*. (Also technically faster.) 2019-06-06 16:36:26 +02:00
431aa4e456 Synced/merged minor cruft from docking branch to minimize drift. AFAIK the only meaningful no-op change is that the call UpdateHoveredWindowAndCaptureFlags() was moved above UpdateMouseMovingNewFrame() to match what docking branch has been doing for a while. 2019-06-06 16:13:30 +02:00
fea5f70611 ImDrawCallback: Allow to override the signature of ImDrawCallback by #define-ing it. This is meant to facilitate custom rendering back-ends passing local render-specific data to the draw callback. 2019-06-06 15:28:37 +02:00
480d57e6a2 Revert "Changed syntax for (very rarely used) IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT mechanism, instead you only need to '#define ImDrawVert MyDrawVert' to use this feature, avoiding the need to declare the entire structure within an awkward macro. Using the old macro will now error with a message pointing you to the new method. (#38, #103, #1172, #1231, #2489)"
This reverts commit 597c024904.
2019-06-06 01:00:30 +02:00
597c024904 Changed syntax for (very rarely used) IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT mechanism, instead you only need to '#define ImDrawVert MyDrawVert' to use this feature, avoiding the need to declare the entire structure within an awkward macro. Using the old macro will now error with a message pointing you to the new method. (#38, #103, #1172, #1231, #2489) 2019-06-06 00:42:27 +02:00
c96f2c4057 Window: Fixed one case where auto-resize by double-clicking the resize grip would make either scrollbar appear for a single frame after the resize. Moved Scrollbar visibility block. 2019-06-05 15:59:14 +02:00
300d8dd656 Internals: Moved scrollbar visibility calculation block below the call to UpdateManualResize(). This commit is _intended_ to have no side-effect (next commit will). Also moved ItemWidthDefault calculation below rectangles. 2019-06-05 15:59:14 +02:00
c1a61d25a7 Scrollbar overlap an extra WindowBorderSize amount on the left to make all distances consistent. Reverted to BorderSize not affecting work/contents rectangles. Scrollbar, Style: Changed default style.ScrollbarSize from 16 to 14. 2019-06-05 15:59:14 +02:00
15282261dd Internals: Minor no-op tidying up toward solving the WindowPadding / WindowBorderSize / ScrollbarSize overlapping mess.
+ Demo: Use SetScrollY().
2019-06-05 15:59:14 +02:00
4149d22e85 Fixed newly created window (e.g. appearing child window) from having scrollbar active on the first frame. (fix 6e03b27) + reworded code a little. (+1 squashed commits)
Fixed auto-resize with AlwaysVerticalScrollbar or AlwaysHorizontalScrollbar flags not taking account of the expect scrollbar sizes.
2019-06-05 15:59:14 +02:00
06f1d2c101 Internals: Storing ScrollMax into a member. Mostly to facilitate debugging. Also locking down window->Scroll slightly lower in the Begin function. 2019-06-05 15:59:13 +02:00
d6df777ff2 TextWrapped, PushTextWrapPos(0.0f) within a window with horizontal scrolling from not covering the full horizontal area (previously only worked with an explicit contents size). 2019-06-05 15:59:13 +02:00
fe32fde376 Internals: Renamed SizeContents to ContentSize, SizeContentsExplicit to ContentSizeExplicit. Tweaked Metrics->Show Rectangles functionality. 2019-06-05 15:59:13 +02:00
f95c77eeea Window rectangles: Changed WorkRect to cover the whole region including scrolling (toward obsolete ContentsRegionRect) + using full WindowPadding*1 padding.
Tweaked InnerClipRect.
TreeNode, CollapsingHeader: Fixed highlight frame not covering horizontal area fully when using horizontal scrolling. (#2211, #2579)
TabBar: Fixed BeginTabBar() within a window with horizontal scrolling from creating a feedback loop with the horizontal contents size.
Columns: Fixed Columns() within a window with horizontal scrolling from not covering the full horizontal area (previously only worked with an explicit contents size). (#125)
Demo: Added demo code to test contentsrect/workrect
2019-06-05 15:59:13 +02:00
a0994d74c2 Clarified behavior of SetNextWindowContentSize(). Content size is defined as the size available after removal of WindowPadding on each sides. So SetNextWindowContentSize(ImVec2(100,100)) + auto-resize will always allow submitting a 100x100 item without creating a scrollbar, regarding of WindowPadding.The exact meaning of ContentSize for decorated windows was previously ill-defined. 2019-06-05 15:59:13 +02:00
09bcf9fbc5 Window rectangles: Made InnerRect not affected by window border sizes. its few users shouldn't be meaningfully affected. 2019-06-05 15:59:12 +02:00
b9874a2423 Comments about obsoleted features version. Todo. Clarify tab bar initial offset (useful if we decide to remove the half-windowpadding clip margin). 2019-06-05 15:58:49 +02:00
57d8ab62f4 Nav: Fixed rare crash when e.g. releasing Alt-key while focusing a window with a menu at the same frame as clearing the focus. This was in most noticeable in some back-ends with emits key release events when focusing another viewport. (#2609) 2019-06-05 00:28:55 +02:00
6614bab883 Combo: Fixed rounding not applying with the ImGuiComboFlags_NoArrowButton flag. (#2606, #2607) 2019-06-04 20:49:29 +02:00
eb7849b477 Nav: Fixed gamepad/keyboard moving of window affecting contents size incorrectly, sometimes leading to scrollbars appearing during the movement. + minor fix with the mostly dead Ctrl+wheel scaling. 2019-05-31 20:48:52 +02:00
cef88f6aae ImDrawListSplitter: Support merging consecutive draw commands straddling two channels. Support zero-init. 2019-05-31 12:06:35 +02:00
f1f4b42d91 ImDrawListSplitter: extracted out of ImDrawList. Down the line we may obsolete the ImDrawList functions and encourage users to store the splitter aside, in the meanwhile ImDrawList holds a splitter.
(This will allow columns/table to recurse.)
2019-05-31 12:03:10 +02:00
8abf1313aa ImDrawList: Fix broken channel splitting (another issue when the first channel is empty) (#2591) + fixed warnings with newer VS 2019-05-31 11:47:00 +02:00
bff7202ff2 Include <alloca.h> also when __SWITCH__ is defined (#2595)
Fixes compilation with devkitPro for Nintendo Switch
2019-05-31 01:52:22 +02:00
42c98c5eea ImDrawList: Fix broken channel splitting (broken by d1e8b69) (#2591) 2019-05-30 18:47:46 +02:00
546b728199 Internals: Window rectangles: Fixed ContentsRegion lag by moving back after Scrollbar, fixes b50c61c9. Shuffling setup order and added comments. 2019-05-30 18:19:14 +02:00
21ebdcafc9 Internals: Window rectangles: Renaming of all rectangles toward their final form. Should be a no-op. Renamed GetWorkRectMax() to GetContentRegionMaxAbs(). Metrics shows SizeContents. 2019-05-30 18:04:21 +02:00
c3d600abed Fixed imgui_impl_opengl3 broken in previous few commits. (#2591, #2593, #2594) 2019-05-30 16:45:59 +02:00
ed79b4d22e Examples/Backends: Metal: Added support for large meshes (64k+ vertices) with 16-bits indices, enable 'ImGuiBackendFlags_HasVtxOffset' config flag in back-end. (#2591, #2592) 2019-05-29 19:45:15 +02:00
7755cbbef2 Renamed ImGuiBackendFlags_HasVtxOffset to ImGuiBackendFlags_RendererHasVtxOffset to match naming convention already used in viewport/docking branch. (#2591) + Fix OpenGL3 code missing flag. 2019-05-29 16:29:17 +02:00
b3dd03f582 Examples/Backends: DirectX9/10/11/12, Vulkan, OpenGL3 (Desktop GL only): Added support for large meshes (64k+ vertices) with 16-bits indices, enable 'ImGuiBackendFlags_HasVtxOffset' config flag in back-end. (#2591) 2019-05-29 16:13:38 +02:00
d1e8b698d0 ImDrawList: Added ImDrawCmd::VtxOffset value to support large meshes (64k+ vertices) using 16-bits indices. To enable the feature, the renderer back-end needs to set 'io.BackendFlags |= ImGuiBackendFlags_HasVtxOffset' and honor the ImDrawCmd::VtxOffset field. Otherwise the value will always be zero. This has the advantage of preserving smaller index buffers and allowing to execute on hardware that do not support 32-bits indices.
ImDrawList: Added ImDrawCmd::IdxOffset value, equivalent to summing element count for each draw command. This is provided for convenience and consistency with VtxOffset. (#2591)
2019-05-29 16:13:38 +02:00
40b9e5e0b4 ImDrawList: Store initial flags for the frame in ImDrawListSharedData, reducing code duplication in setting up the flags. 2019-05-29 14:26:03 +02:00
cb7ba60d3f CollapsingHeader: When a close button is enabled, better clip the label to avoid overlap. (#600) 2019-05-28 21:25:28 +02:00
c487bc52a2 Fonts: Added some details about using custom colorful icons. 2019-05-28 20:17:15 +02:00
70d9f79312 Internal: Renamed InnerMainRect to InnerVisibleRect. Printing coordinates in Metrics window. 2019-05-28 11:23:04 +02:00
2742663ad2 Changelog, minor tweaks. (#2585) 2019-05-28 11:23:04 +02:00
c0e690318a Examples: imgui_impl_osx: Added mouse cursor support. (#2585, #1873) 2019-05-28 11:15:59 +02:00
2d68e892a8 Added full "Dear ImGui" prefix to the title of "Dear ImGui Demo" and "Dear ImGui Metrics" windows. Shortened amount of nodes in columns>tree demo. 2019-05-27 18:38:28 +02:00
9c35344175 Comments, todo entries, moved ImGuiSelectableFlagsPrivate in higher ranges to match others. 2019-05-27 16:50:56 +02:00
70a4be07df ColorEdit: Fixed the color picker popup only displaying inputs as HSV instead of showing multiple options. (#2587, broken in 1.69 by #2384). 2019-05-27 14:57:39 +02:00
affa7e2422 Examples: imgui_impl_opengl3: Fix empty printout on shader load. (#2584)
Fixed minor bug in CheckShader and CheckProgram

The log_length reported by 
glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &log_length)
will at least return 1, since the string delimiter is also counted.

The old version would always print and empty string to stderr. This is annoying in the emscripten port, since it prints a red error message to the Javascript console. The new version fixes this behavior.
2019-05-27 10:47:18 +02:00
958d75c00a Style: Added style.WindowMenuButtonPosition (left/right, defaults to ImGuiDir_Left) to move the collapsing/docking button to the other side of the title bar. 2019-05-24 21:54:52 +02:00
6c3697f6f1 Internal: CloseButton takes an upper-left corner + a size to be consistent with similar widgets. 2019-05-24 17:58:21 +02:00
ec3ec24157 Internals: Extracted some of the tab bar shrinking code into a ShrinkWidths() function so columns/table can use it. 2019-05-24 14:32:33 +02:00
3fda90d6a7 Fixed InputScalar, InputScalarN, SliderScalarN, DragScalarN with non-visible label from inserting style.ItemInnerSpacing.x worth of trailing spacing. 2019-05-24 14:32:28 +02:00
7bc03f7155 Internals: Added InnerWorkRect equal to old InnerClipRect, added InnerWorkRectClipped actually clipped. 2019-05-22 23:56:31 +02:00
b85e97137d Version tag is 1.71 WIP oops 2019-05-22 23:56:26 +02:00
a2eec8f5b5 Fix OuterRectClipped not being clipped correctly, which resulted in child window outside visible bound to not be marked with SkipItems. Broken in b50c61c961.
+ Comments on InnerClipRect being misleading. Demo: Tweak to sizing of child window in the Layout->Scrolling section.
2019-05-22 22:14:31 +02:00
34b881eb12 ImFontGlyphRangesBuilder: Fixed unnecessarily over-sized buffer, which incidentally was also not fully cleared. Fixed edge case overflow when adding character 0xFFFF. (#2568) 2019-05-21 12:45:27 +02:00
882d2c3aea Fixed crash when appending with BeginMainMenuBar() more than once and no other window are showing. (#2567) + comments 2019-05-21 12:18:34 +02:00
392ab08580 BeginPopupContextItem(): Skip processing when SkipItems is set as LastItemId is unreliable and we assert when it is zero. + Minor comments on columns. 2019-05-20 16:46:47 +02:00
f242cd4d8a Fixed GCC mem-access warnings (#2565)
+ using "if defined" more consistently for Clang.
2019-05-19 17:15:14 +02:00
31e3e861ef Update changelog, comments, made empty/no-text clipboard return NULL as with other implementation. Minor style tweaks. (#2546)
Fixed IMGUI_DISABLE_WIN32_FUNCTIONS not disabling IME code.
2019-05-18 17:44:09 +02:00
02de498a41 Add native mac copy/paste support to match win32 (#2546) 2019-05-18 17:34:58 +02:00
e6109a9145 Fixed ColorEdit breakage introduced by d3a387c (#2557, #1875, #2034) 2019-05-18 11:18:31 +02:00
679cf7434e Fix undefined behavior (#2561) 2019-05-18 10:43:30 +02:00
fc3c3de551 Fixed uses of IsItemDeactivated(), IsItemDeactivatedAfterEdit() on multi-components widgets and after EndGroup(). (#2550, #1875) 2019-05-13 19:05:41 +02:00
d3a387cc18 Fixed InputFloatX, SliderFloatX, DragFloatX functions erroneously reporting IsItemEdited() multiple times when the text input doesn't match the formatted output value (e.g. input "1" shows "1.000"). It wasn't much of a problem because we typically use the return value instead of IsItemEdited() here. (#1875, #2034) 2019-05-13 19:04:57 +02:00
99a845053a Internal: Renamed fields + minor tweaks (probably shallow break stack-layout pr, sorry!) 2019-05-13 18:26:28 +02:00
64dbd932d2 Internal: Removed GetNextItemWidth(), relying on ItemAdd or NextItemData.ClearFlags() to clear the width data. Amend 5078fa20 and undo some of its effects of imgui_widgets.cpp 2019-05-13 15:29:00 +02:00
632469d2e5 Renamed SetNextTreeNodeOpen() to SetNextItemOpen(). Refactored SetNextItemXXX stuff to match SetNextWindowXXX code closely. 2019-05-13 15:11:25 +02:00
36e714a459 Internal: Storing flags for NextWindowData so that we can clear everything with a single write and remove dummy condition fields. 2019-05-13 14:57:30 +02:00
0b485f12d7 Internal: Minor tidying/reordering of sections within ImGuiContext / window DC. 2019-05-13 14:02:03 +02:00
7355c84701 Tweak EndGroup() to facilitate fixing #2550 later (currently should have no side-effect0. Demo: Add extra widget to status query test. 2019-05-12 21:42:36 +02:00
aca6ee1a91 Cast ImTextureId to void* before printing in Metrics window. (#2548) 2019-05-11 11:34:41 +02:00
87c5356d97 FreeType: Added RasterizerFlags::Monochrome flag to disable font anti-aliasing. (#2545) Combine with RasterizerFlags::MonoHinting for best results. 2019-05-11 10:46:26 +02:00
ef13d95466 IO: changed AddInputCharacter(unsigned short c) signature to AddInputCharacter(unsigned int c).
Examples/Backends: Don't filter characters under 0x10000 before calling io.AddInputCharacter(), the filtering is done in io.AddInputCharacter() itself. This is in prevision for fuller Unicode support. (#2538, #2541)
2019-05-11 10:33:56 +02:00
7c256fbd40 Internal: Extracted some of the Begin code into RenderWindowDecorations(). 2019-05-10 22:45:52 +02:00
72951a1a85 Internal: Extracted some of the Begin code into RenderWindowTitleBarContents(). 2019-05-10 22:45:28 +02:00
b50c61c961 Internal: Begin: Update rectangles before Scrollbar() which now uses them. Fixes 39eeda0. 2019-05-10 22:30:33 +02:00
39eeda0227 Internal: Scrollbar: Further sane simplification (using InnerMainRect instead of duplicating calculations). 2019-05-10 18:52:29 +02:00
37174c85e2 Internal: Scrollbar: Extracted scrollbar code for other uses (eg. table v2 scrolling without using a child window). 2019-05-10 18:52:23 +02:00
9534ef9b26 Separator: Revert 1.70 "Declare its thickness (1.0f) to the layout" change (c5d83d8a). It's not incorrect but it breaks existing some layout patterns. Will return back to it when we expose Separator flags. 2019-05-09 17:52:56 +02:00
e29176df53 Internals: Columns: Renamed fields. Comments and tweak. Moved a demo block. 2019-05-09 13:12:09 +02:00
a4d0b0efa4 Internal: Refactored Separator into SeparatorEx(), exposed ImGuiSeparatorFlags_SpanAllColumns in imgui_internal.h and support without. (#759) + misc comments 2019-05-09 12:55:01 +02:00
b7c2759f95 Columns: Fixed Separator from creating an extraneous draw command. Fixed Selectable with SpanAllColumns flag from creating an extraneous draw command. (#125) 2019-05-09 12:10:36 +02:00
42fc563fed Version 1.71 WIP + fixed minor typo 2019-05-07 16:36:08 +02:00
d1d5075b66 Version 1.70 2019-05-06 14:17:39 +02:00
d88121ff5b Examples: DirectX9/10/11: Taking reference to device + subsequent merge of this in docking will fix DX9 issue #2524 2019-05-06 10:15:22 +02:00
6c196cf432 Examples Readme and Changelog tweaks, added #2527, re-ordered examples/README alphabetically. 2019-05-06 10:02:59 +02:00
5ecc9d5865 Examples: Metal: Add GLFW+Metal example 2019-05-06 09:51:21 +02:00
526e2303bc Window: Fixed SetNextWindowSizeConstraints() with non-rounded positions making windows drift. (#2067, #2530) 2019-05-03 19:09:44 +02:00
9c1f02a42c Misc: Made IMGUI_CHECKVERSION() macro also check for matching size of ImDrawIdx. 2019-05-03 18:42:53 +02:00
e2166db282 Internals: Fixed incorrect repeat delay/rate calculation in IsMouseClicked() with repeat flag leading to involontary but thankfully doubling the rate. Using our standard function, making the multiplicator explicit. 2019-05-03 15:06:06 +02:00
2dc81057ec Selectable: With ImGuiSelectableFlags_AllowDoubleClick doesn't return true on the mouse button releas efollowing the double-click. Only first mouse release + second mouse down (double-click) returns true. Likewise for internal ButtonBehavior() with both _PressedOnClickRelease | _PressedOnDoubleClick. (#2503) 2019-05-03 14:31:12 +02:00
86f92fe756 Demo: Improved trees in columns demo. (#2136) 2019-05-02 21:32:36 +02:00
ce19cb465f Internals: Rename GetContentRegionMaxScreen() -> GetWorkRectMax(). At this point this is mostly useful to facilitate merge of other branches. 2019-05-02 16:29:40 +02:00
a1c432d1ad Internals: SettingsHandlerWindow_ReadLine uses context parameter. 2019-05-02 14:30:35 +02:00
ae405b83a4 Examples: Added missing per-renderer local changelogs. (#2037, #1639, #2452) 2019-04-30 22:28:29 +02:00
7c6ba3a1da ImDrawCallback_ResetRenderState: Added Metal. 2019-04-30 22:18:25 +02:00
5c1cd5c8c7 ImDrawCallback_ResetRenderState, Examples: Added support for reset render state callback. (#2037, #1639, #2452) 2019-04-30 22:15:59 +02:00
3fbc0b7a9e Obsoleted GetContentRegionAvailWidth(), use GetContentRegionAvail().x instead. Kept inline redirection function. 2019-04-29 18:33:08 +02:00
db2d58a68b Drag and Drop: Fixed drag source with ImGuiDragDropFlags_SourceAllowNullID and null ID from receiving click regardless of being covered by another window (it didn't honor correct hovering rules). (#2521) 2019-04-29 16:34:02 +02:00
0f2852806c Amend 48a09a7 with changelog, breaking changes, tweak demo code for spacing. (#2518) 2019-04-29 12:44:17 +02:00
4c0f34fd5d Improved algorithm for mitre joints on thick lines 2019-04-29 12:07:03 +02:00
4dec744795 Tidying up BeginMenu() code + comments. 2019-04-29 00:02:02 +02:00
842a720e72 Popups: Closes popup at the time of FocusWindow(). Fixes right-click from closing all popups instead of aiming at the hovered popup level (regression in 1.67's ae76a1fd). 2019-04-28 22:33:58 +02:00
bda2cde68e Popups: Closing a popup restores the focused/nav window in place at the time of the popup opening, instead of restoring the window that was in the window stack at the time of the OpenPopup call. (#2517)
Among other things, this allows opening a popup while no window are focused, and pressing Escape to clear the focus again.
2019-04-28 22:18:51 +02:00
3276b12765 Internals: Added DataTypeApplyOp, DataTypeApplyOpFromText to imgui_internal.h 2019-04-28 20:55:51 +02:00
09db2f6dec Fix 61d9258 when there is not scrollbar "Window: Fixed contents region being off by WindowBorderSize amount on the right when scrollbar is active." 2019-04-28 18:50:51 +02:00
4e81b2d093 Internals: Renaming. Renamed ImGuiPopupRef to ImGuiPopupData for consistency and added constructor. 2019-04-28 17:15:08 +02:00
3d363c91fd Internals: Exposed ImGuiDataTypeInfo, DataTypeGetInfo(), DataTypeFormatString(). Comments. 2019-04-28 15:27:18 +02:00
00b3c830db Internals: Begin: Moved OuterRectClipped/InnerMainRect/InnerClipRect computation higher up in the function, next to ContentsRect/WorkRect code. Removed commented out debug drawing code which is now available in Metrics window. 2019-04-26 23:33:09 +02:00
61d92580aa Window: Fixed contents region being off by WindowBorderSize amount on the right when scrollbar is active. 2019-04-26 23:32:29 +02:00
5d799d76ea Internals: Nav scrolling uses InnerMainRect instead of InnerClipRect. 2019-04-26 23:31:51 +02:00
c5d83d8af2 Separator: Declare its thickness (1.0f) to the layout, making items around separator more symmetrical. 2019-04-26 23:31:31 +02:00
56c3aaf6bd Nav: Fixed Drag/Slider functions going into text input mode when keyboard CTRL is held while pressing NavActivate. 2019-04-25 17:50:40 +02:00
dd15b44230 Internals: TempInputText: Tidying up DragScalar / SliderScalar / TempInputTextScalar. 2019-04-25 17:50:40 +02:00
0ca1675ff9 Internals: TempInputText: Rename InputScalarAsWidgetReplacement() -> TempInputTextScalar(), ScalarAsInputTextId -> TempInputTextId, small tidying up in affected functions. 2019-04-25 16:03:47 +02:00
59a3f0476d Internals: Using more explicit PushOverrideID() helper + renamed equivalent internal tree helper. 2019-04-25 15:21:22 +02:00
1ca6e5b59f Examples: Glut: Added note about missing cursor support. (#2375, #2465) 2019-04-25 12:01:01 +02:00
4dc4ace864 Window: Fixed window with the AlwaysAutoResize flag unnecessarily extending their hovering boundaries by a few pixels (this is used to facilitate resizing from borders when available for a given window). One of the noticeable minor side effect was that navigating menus would have had a tendency to disable highlight from parent menu items earlier than necessary while approaching the child menu.
+ Changelog fixed unfinished sentence and tweaks,
2019-04-25 11:50:28 +02:00
16b18b265e MenuItem, BeginMenu: Fix undesirable tall frames in horizontal layout context, which would be visible when trying to use rounded selectable/menus.
PushStyleVar: Added comments in the assert message.
Minor tweaks.
2019-04-25 11:34:07 +02:00
6db0766564 Misc comments, internal renaming, added disable indentation option to Columns demo section. 2019-04-24 17:40:07 +02:00
6789ea3482 Examples: SDL: Gamepad support minor amend. Fixes ImGuiBackendFlags_HasGamepad not being set. Enable in Emscripten demo. Tweaks. (#2509, #2484). 2019-04-23 12:38:59 +02:00
994a92d79d Added support to use controllers via SDL_GameController. (#2509)
Updated sdl examples to use SDL_INIT_GAMECONTROLLER flag
2019-04-23 12:14:05 +02:00
16e9b8191b Increased IMGUI_VERSION_NUM arbitrarily, help narrowing down reports that don't include a commit hash. Add comments. 2019-04-22 11:16:17 +02:00
f159eb35fb Examples: SDL: Removed unused code. (#2484) 2019-04-22 10:43:14 +02:00
59f012d656 Internals: ImHashStr() default parameter. 2019-04-19 19:48:51 +02:00
5078fa208b Added SetNextItemWidth() helper to avoid using PushItemWidth/PopItemWidth() for single items. 2019-04-18 18:29:28 +02:00
8d53f834ee Demo: Documents: Fix misusage of ListBoxHeader(). 2019-04-18 18:24:51 +02:00
0e46d65b03 Misc: Fixed PushItemWidth(-width) (for right-side alignment) laying out certain items (button, listbox, etc.) with negative sizes if the 'width' argument was smaller than the available width at the time of item submission, 2019-04-18 15:46:13 +02:00
a1cf7d636d Internals: Rework CalcItemWidth / CalcItemSize but make their similarities and their differences more obvious. (#2449) 2019-04-18 15:46:13 +02:00
f355a40367 Added commentary about ContentRegion functions. Added internal GetContentRegionMaxScreen() to facilitate internal code at the moment. 2019-04-18 15:46:13 +02:00
9d4a893a77 Internals: Moved CalcItemSize next to CalcItemWidth, added comments to clarify their respective intent. Should have no side effect. 2019-04-18 15:46:12 +02:00
240dddff87 Combo, Slider: Improve rendering in situation when there's there's very little space available. 2019-04-18 15:46:12 +02:00
1aeee9d40f Internals: Columns: Tweaks, renaming. Metrics: Show rectangles for child windows.
Renamed SameLine() first parameter.
2019-04-17 22:12:17 +02:00
1d3ebef364 Columns: Fixed boundary of clipping being off by 1 pixel within the left column. 2019-04-17 21:51:13 +02:00
74a3878be4 emscripten: replace shell_minimal.html with 'soft fullscreen' version 2019-04-17 11:59:26 +02:00
1f25cdd6b4 Clarified asserts comments + todo entries. (#2500) 2019-04-17 09:59:03 +02:00
7baf45cffa Metrics: Added "Show windows rectangles" tool to visualize the different rectangles. 2019-04-16 22:02:56 +02:00
742b5f4c68 Merged a bunch of small changes from Docking branch to reduce the difference between branches.
Noticeable: horizontal alignment of CloseButton. Menu fill take account of border. Various stylistic tweaks to accomodate other changes in Docking.
2019-04-16 13:07:43 +02:00
311469e9d6 Internals: Columns: Some renaming, extracted code into GetColumnsID(). 2019-04-16 11:58:54 +02:00
8130fd9816 Examples: DirectX10/11/12, Allegro, Marmalade: Render functions early out when display size is zero (minimized). (#2496) 2019-04-15 18:47:36 +02:00
1fe6533192 Examples: Emscripten: Tweaks for size. (#2494) 2019-04-15 17:18:31 +02:00
35cbf9c052 Examples: Visual Studio: Updated default platform toolset+sdk in vcproj files from v100+sdk7 (vs2010) to v110+sdk8 (vs2012). This is mostly so we can remove reliance on DXSDK_DIR for the DX10/DX11 example, which if existing and when switching to recent SDK ends up conflicting and creating warnings. 2019-04-15 15:48:38 +02:00
eeea7da3d0 Examples: Emscripten: Fixed error in shell template. (#2494) 2019-04-15 01:46:34 +02:00
c1848b185c Examples: Emscripten: Switched to WebGL1/ES2, Added Changelog, Updated links, Added ignore list, Fixed warning with older versions. Removed reliance on C++11 (would warn on some compiler). Improved html template, removed undesirable options, reduced log size. Tweaked main.cpp. (#2494) 2019-04-15 01:28:44 +02:00
882d480b5e Examples: Removed unused variable (will be used in docking branch tho, undo when merging!) 2019-04-15 01:01:39 +02:00
622556719e Merge branch 'standalone-emscripten' of https://github.com/nicolasnoble/imgui 2019-04-15 00:36:56 +02:00
a936d0669c Adding standalone Emscripten example. 2019-04-13 22:39:42 +02:00
e805ca29d8 Internals: Moved resize grips and borders to nav layer 1 so that testing system doesn't attempt to scroll to get them inside the InnerRect. 2019-04-13 18:51:32 +02:00
fb2626c21b Tests: Added hook/tweaks for imgui-test engine. + Fixed warnings. 2019-04-13 00:29:27 +02:00
30d81f53cb PlotLines, PlotHistogram: Ignore NaN values when calculating min/max bounds. (#2485) 2019-04-12 22:16:59 +02:00
ee02cdbf03 Internals, Docs: Added a bunch of clarification about ButtonBehavior in the form of a table (and to facilitate writing tests) 2019-04-12 17:49:40 +02:00
07a70dc972 Internals: Merge minor things from range_select branch. Added ImGuiButtonFlags_NoHoveredOnNav. Added IsItemToggledSelected() - unused here. Renaming. 2019-04-11 15:40:36 +02:00
570d0bbbda Demo: Comments, tweaks, removed some uses of ImColor helpers. 2019-04-11 15:23:54 +02:00
b8fe0df7df Examples: Null: Added Makefile. 2019-04-08 19:16:45 +02:00
1391904fd2 Internals: Selectable: Added ImGuiSelectableFlags_AllowItemOverlap in imgui_internal.h (~ #684, #2341) 2019-04-08 17:59:25 +02:00
b53630813e Internals: Tweak ItemSize calls. Added todo items. 2019-04-08 16:13:51 +02:00
42423d5ea4 Examples: Makefile: Tweaks so they are more consistent with each others. Added -g./opt/local includes for MacPorts on Mac OS X. (#297) 2019-04-07 23:02:07 +02:00
1295205cd4 Examples: Vulkan: Fixed warnings. (#2480) 2019-04-07 22:27:45 +02:00
ccca76fdea Merge branch 'vulkan_fix_master' 2019-04-07 16:22:47 +02:00
302af7b2c9 FAQ tweaks. Add missing entries in imgui.cpp (which until now where only in the README). 2019-04-07 16:22:41 +02:00
c43dab2414 Vulkan: Fix not incrementing semaphore index. (#2472, #2071) 2019-04-07 15:57:07 +02:00
e099a7dc74 Vulkan: Bits. Using IM_ALLOC/IM_FREE instead of new[] / delete[]. 2019-04-05 20:27:46 +02:00
c8fd4afd75 Misc: Added IM_MALLOC/IM_FREE macros mimicking IM_NEW/IM_DELETE so user doesn't need to revert to using the ImGui::MemAlloc()/MemFree() calls directly. 2019-04-05 20:20:24 +02:00
bd351e9ac5 Misc: Added IM_MALLOC/IM_FREE macros mimicking IM_NEW/IM_DELETE so user doesn't need to revert to using the ImGui::MemAlloc()/MemFree() calls directly. 2019-04-05 20:20:08 +02:00
6bc47dfe48 Vulkan: Removed superfluous vkInstance parameters being passed along. 2019-04-05 18:24:28 +02:00
452047c7ca Vulkan: Removed requirement for user to pass their own render buffer storage to ImGui_ImplVulkan_RenderDrawData(), this is managed internally. 2019-04-05 18:24:28 +02:00
ec76722d2d Vulkan: Added ImageCount to InitInfo structure (!= MinImageCount) will be needed for viewports. Renamed FramesQueueSize -> ImageCount. (#2472, #2071) 2019-04-05 17:22:24 +02:00
a45840746e Vulkan, Viewports: Fix for resizing viewport windows crashing. (#2472) 2019-04-05 17:04:12 +02:00
0034e65c26 Vulkan: Renaming demo/helper structures. Tidying up examples main.cpp. 2019-04-04 23:40:28 +02:00
4f54a527ab Vulkan: Renaming, we want InitInfo to source MinImageCount which is the "source" value (so viewport creation can use this). Made ImGui_ImplVulkan_DestroyFrameRenderBuffers public. (#2071) 2019-04-04 23:13:31 +02:00
86f5945f49 Vulkan: Storing user info into a single g_VulkanInitInfo structure to simplify code. 2019-04-04 23:13:31 +02:00
66f4be2e13 Vulkan: Added extra parameter to ImGui_ImplVulkan_RenderDrawData(). User is in charge of owning/storing 1 ImGui_ImplVulkan_FrameRenderBuffers per in-flight rendering frame. Removed ImGui_ImplVulkan_SetFramesQueueSize. (#2461, #2348, #2378, #2097, #2071, #1677) 2019-04-04 22:27:29 +02:00
6bf981c85c Vulkan: More renaming. Comments. 2019-04-04 22:20:01 +02:00
f586764cdd Examples: Vulkan: Merged helpers into ImGui_ImplVulkanH_CreateWindowData. Removed ImGui_ImplVulkan_InvalidateFrameDeviceObjects from API. Comments. (#2071) 2019-04-04 22:12:16 +02:00
54b8a65d9e Examples: Vulkan: Renamed QueuedFramesCount to FramesQueueSize. Moved Framebuffer, Backbuffer to FrameData structure. (#2071) 2019-04-04 22:12:15 +02:00
317859a3da Examples: Vulkan: Updated Changelog, removed debug code, tweaked code, made GLFW/SDL match each others. Initialize FrameDataForRender fields. Added Assertion. Clearing fields on DestroyFrameData(). (#2071) 2019-04-04 22:11:13 +02:00
c7eef99a33 Examples: Vulkan: Fixed tabs->space, removed extraneous braces and empty lines. (#2071) 2019-04-04 22:10:43 +02:00
b88a3b2711 Examples: Vulkan: Added calls to supports runtime changing back buffer count. (#2071) 2019-04-04 22:10:43 +02:00
1c3311e4d6 Vulkan: Avoid passing negative coordinates to vkCmdSetScissor, which debug validation layers do not like. 2019-04-04 22:09:26 +02:00
fc52364652 Tabs to Spaces, comments. 2019-04-03 17:25:02 +02:00
cdb109f617 Renamed freeglut vcxproj files + Comments, Changelog (#2465) 2019-04-03 16:25:35 +02:00
ece322ff12 freeglut -> glut rename 2019-04-03 07:19:31 -07:00
3fad375f5f ifdef freeglut extensions properly 2019-04-03 07:19:31 -07:00
81f70e5b7c Fixups for OSX 2019-04-03 07:19:31 -07:00
a402f5b9a9 Add makefile for freeglut 2019-04-03 07:19:31 -07:00
5c4cc370bb Examples: Vulkan: Added shader sources/references in the .cpp source. 2019-04-03 11:23:54 +02:00
8dab7ac021 InputText: Made Shift+Tab consistently do nothing regardless of whether the back-end emits both char and keys or just keys. (#2467, #1336) 2019-04-03 11:14:34 +02:00
da035ced97 InputText, Examples/SDL: Emulate \t input if back-end doesn't provide it. (#1336, #2467)
+ Fix some output filename in SDL build batch files.
2019-04-03 11:04:00 +02:00
01e29a3933 InputText: Fixed ImGuiInputTextFlags_AllowTabInput leading to two tabs characters being inserted if the back-end provided both Key and Character input. (#2467, #1336) 2019-04-03 10:45:51 +02:00
4a57507f75 InputText: Work-around for buggy standard libraries where isprint('\t') returns true. (#2467, #1336)
Not using isprint. + todo items.
2019-04-03 10:40:14 +02:00
e3cd6b1cbb Examples: Vulkan: Using IM_ARRAYSIZE() where possible. 2019-04-02 15:34:16 +02:00
3a737e665a Examples: Vulkan: Added missing support for 32-bit indices (#define ImDrawIdx unsigned int). + demo typo 2019-04-02 10:36:35 +02:00
d9568c717d Silencing -Wstack-protector (#2459) 2019-03-31 01:35:03 -07:00
e21bbee311 Examples: DirectX9: Fixed erroneous assert in ImGui_ImplDX9_InvalidateDeviceObjects(). FreeType: Fixed suggested code to not require an initial build call.. (#2454) 2019-03-29 18:32:57 +01:00
163779da51 Examples: DirectX12: Various tidying up. 2019-03-29 16:23:37 +01:00
512d39d031 Examples: OpenGL3: Minor tweaks, clarifications + not calling glBindBuffer more than necessary in the render loop. 2019-03-29 16:17:30 +01:00
9a0e71a6ec Internals: Renamed the ImGuiWindow HiddenFrameXXX fields to decorrelate them from resizing behavior, as those values are set by other logic. 2019-03-28 15:41:49 +01:00
20188b19d6 Comments (#2441) + Freeglut fixes (#2430) 2019-03-26 12:16:23 +01:00
cf1b02e54e Rearrange code in UpdateMouseWheel(). (#2424, #1463) + Fix old io.FontAllowUserScaling feature (probably should be made obsolete, but until then best fixed) 2019-03-25 19:40:19 +01:00
1963cc59be Implement horizontal scrolling with Shift+Scroll
This is standard scrolling behaviour in most applications.
2019-03-25 19:09:40 +01:00
3d8ea352d1 InputText: Fixed selection background starts rendering one frame after the cursor movement when first transitioning from no-selection to has-selection. (Bug in 1.69) (#2436) [@Nazg-Gul] 2019-03-25 16:06:30 +01:00
abb7d7b18a InputText: Simplify read-only code path. 2019-03-25 15:50:23 +01:00
d9f6ba3035 IsWindowHovered() made change which should have no effect in master but fix result of IsWindowHovered(ImGuiHoveredFlags_ChildWindows) over multiple viewport in docking branch. (#2432) 2019-03-25 15:39:11 +01:00
a53c57152b Mention Julia binding in README (#2446)
Thank you!
2019-03-23 19:32:19 -07:00
221bf93a55 Comments, todo list, remove trailing spaces. 2019-03-17 00:56:21 +01:00
857381b9ca GetMouseDragDelta(): also returns the delta on the mouse button released frame. Verify that mouse positions are valid otherwise returns zero. Removed obsolete comment. Tweaked demo. (#2419) 2019-03-15 15:03:37 +01:00
ff03ae503b Examples: OpenGL: Added a dummy GL call + comments in ImGui_ImplOpenGL3_Init() to detect uninitialized GL function loaders early, and help users understand what they are missing. (#2421) 2019-03-15 13:09:07 +01:00
cf2c52282d Version 1.70 WIP 2019-03-15 13:07:30 +01:00
ebe79bbed0 Demo: Custom rendering: Minor sizing issue fix. 2019-03-13 15:44:23 +01:00
55c02099c5 Version 1.69, comments, typos 2019-03-13 15:29:43 +01:00
a26085ed53 Internals: Fixed Navigation from reaching ImGuiItemFlags_Disabled items (#211) + Examples comments 2019-03-12 22:23:56 +01:00
53e0c13be2 TabBar: Reworked scrolling policy (when ImGuiTabBarFlags_FittingPolicyScroll is set) to teleport the view when aiming at a tab far away the visible section, and otherwise accelerate the scrolling speed to cap the scrolling time to 0.3 seconds. 2019-03-12 20:57:02 +01:00
99d8425173 TabBar: Fixed Tab tooltip code making drag and drop tooltip disappear during the frame where the drag payload activate a tab. 2019-03-12 18:56:19 +01:00
cfa8f672f6 Examples: GLFW, SDL: Preserve DisplayFramebufferScale when main viewport is minimized. (This is particularly useful for the viewport branch because we are not supporting per-viewport frame-buffer scale. It fixes windows not refreshing when main viewport is minimized.) (#2416) 2019-03-12 18:27:14 +01:00
495065f790 Fixed Clang and PVS warnings. 2019-03-12 12:08:51 +01:00
f254168335 InputText: Fixed c779fbb leading to display of the wrong buffer when resizing a buffer. (#2400, #2006, #1443, #1008). 2019-03-12 11:56:40 +01:00
897badec7a Demo: InputText: Demonstrating use of ImGuiInputTextFlags_CallbackResize. (#2006, #1443, #1008). 2019-03-12 11:24:49 +01:00
a92c587c75 Added GetGlyphRangesVietnamese() helper. (#2403) 2019-03-11 22:02:59 +01:00
65c2220049 Internal: Removed unused fields from ImGuiMenuColumns. 2019-03-11 20:14:56 +01:00
6767b0a1b0 Examples: Win32+DirectX: moved helper functions below main. 2019-03-11 16:00:18 +01:00
b5d57a6615 Fix typos. (#2413) 2019-03-09 10:10:17 +01:00
17c567c3a9 Don't use const qualified parameters in declarations.
This fixes warnings from clang-tidy like this:

    parameter 'v_max' is const-qualified in the function declaration;
    const-qualification of parameters only has an effect in function definitions

Since values (rather than references or pointers) don't need to be
const, they don't need to be marked that way in the function declaration.
2019-03-08 18:21:11 +01:00
79bb4ce128 Added ImGuiColorEditFlagsFlags_InputHSV. (#2383, #2384) 2019-03-08 18:16:41 +01:00
8e0e91827f ColorEdit: Fixed tooltip not honoring the ImGuiColorEditFlags_NoAlpha contract of never reading the 4th float in the array (value was read and discarded). (#2384) 2019-03-08 18:16:41 +01:00
66936880ba Moved placeholder sections to match Docking branch. Comments. 2019-03-08 18:16:41 +01:00
3b11505481 Fix typos. (#2411) 2019-03-08 17:52:32 +01:00
f717df4eb6 Internal: Columns: Allow to use BeginColumns(1) so code designed for variable number of columns can still call NextColumn etc. (#125) 2019-03-07 18:22:28 +01:00
e9651aaa77 TabBar: Fixed ImGuiTabItemFlags_SetSelected being ignored if the tab is not visible (with scrolling policy enabled) or if is currently appearing. 2019-03-07 17:45:59 +01:00
1c23981782 Made ImS8 and ImS16 explicitly signed in case some crazy SDK decide to flip the signedness over. (#2408) 2019-03-07 16:10:44 +01:00
8464df1f6e Internals: ColorEdit: Minor optimizations. Initialize internal arrays as static const, avoid unnecessary HSV->RGB conversion. 2019-03-06 19:30:34 +01:00
ea8158acdf Demo: Renamed ShowHelpMarker() -> HelpMarker(). Fixed minor PVS warning. Removed unnecessary casts. 2019-03-06 18:24:07 +01:00
510342f024 Examples: DirectX9: Minor changes to match the other DirectX examples more closely. (#2394) 2019-03-06 18:00:04 +01:00
c779fbb651 InputTextWithHint: Fix for Password fields. Update changelog, demo. (#2400) 2019-03-06 17:33:24 +01:00
ab80ee6453 Added InputTextWithHint() (#2400)
Squashed commit of the following:

commit 1970d84051d3878f8c1354d9c33c795d9c66143f
Author: Lucas Lazare <lazarelucas@yahoo.fr>
Date:   Tue Mar 5 12:20:39 2019 -0500

    Removing sneaky tabulations #2 (why, editor T-T)

    I should update my settings, I guess

commit 219bdfcb7fbd17edf3048cb0edfde2532e4d6ac3
Author: Lucas Lazare <lazarelucas@yahoo.fr>
Date:   Tue Mar 5 12:17:27 2019 -0500

    Removing useless check introduced in b0d172

commit 8afd7a2b459df0eb14eca88d832d2bebd1e684e6
Author: Lucas Lazare <lazarelucas@yahoo.fr>
Date:   Tue Mar 5 11:49:24 2019 -0500

    Removing sneaky tabulations

commit 8e0490863126d63cafc782a6aac8707e44f95653
Author: Lucas Lazare <lazarelucas@yahoo.fr>
Date:   Tue Mar 5 11:45:13 2019 -0500

    Moving InputTextHinted code to InputTextEx

commit b0d1723a2fb02d17ba15b9c1e679dedbbe3c17fd
Author: Lucas Lazare <lazarelucas@yahoo.fr>
Date:   Tue Mar 5 00:23:02 2019 -0500

    C++11 to C++98

commit 9afeae399826015357962607b4aeb0109fde698e
Author: Lucas Lazare <lazarelucas@yahoo.fr>
Date:   Mon Mar 4 23:43:28 2019 -0500

    Added InputTextHinted
2019-03-06 17:33:05 +01:00
fe48368cb2 InputText: Moving some code in anticipation of supporting hint display with password. This commit is aimed at having no visible side effect. (#2400) 2019-03-06 15:45:11 +01:00
344140004b Fixed IsItemDeactivated()/IsItemDeactivatedAfterEdit() from not correctly returning true when tabbing out of a focusable widget (Input/Slider/Drag) in most situations. (#2215, #1875)
+ Minor renaming of a local variable in widget code.
2019-03-05 22:09:25 +01:00
26328fc9fe Internal: Tabbing/Focus: Tidying up old code, moved some state to context instead of window. Storing new data will allow us to fix the bug mentioned in #2215 (probably in next commit). 2019-03-05 19:51:27 +01:00
9c45072cb0 Demo: Added flags to InputTextMulttiline() demo. 2019-03-05 19:25:07 +01:00
076be7ec41 MenuItem, Selectable: Fixed disabled widget interfering with navigation (fix c2db7f63 in 1.67). 2019-03-05 19:00:19 +01:00
ce4e62649a Internal: Tabbing: Tweaks to FocusableItemRegister and using the standard mechanism to allow/block Tab being interpreting by tabbing instead of InputText() widget. 2019-03-05 18:24:59 +01:00
1ed3c4cf4a Internal: Text: Extracted TextUnformatted into TextEx over which we can freely atter the signature. Clarified current large text behavior of TextUnformatted with explicit ImGuiTextFlags_NoWidthForLargeClippedText flag (always set). 2019-03-05 17:35:45 +01:00
622a27506a Text: Fixed large Text/TextUnformatted call not declaring its size when starting below the lower point of the current clipping rectangle. Somehow this bug has been there since v1.0! It was hardly noticeable but would affect the scrolling range, which in turn would affect some scrolling request functions when called during the opening frame of a window. 2019-03-05 15:23:11 +01:00
ac4842fa17 Nav: Fixed Ctrl+Tab keeping active InputText() of a previous window active after the switch. (#2380) 2019-03-05 12:03:54 +01:00
f4dd990e38 Comments and Issue Template 2019-03-05 11:03:32 +01:00
94e794f81b Renamed GetOverlayDrawList() to GetForegroundDrawList() for consistency. Kept redirection function (will obsolete). (#2391)
Demo: Using GetBackgroundDrawList() and GetForegroundDrawList() in "Custom Rendering" demo.
2019-03-04 16:35:50 +01:00
96b13760d4 Added GetBackgroundDrawList() helper to quickly get access to a ImDrawList that will be rendered behind every other windows. (#2391) 2019-03-04 16:10:51 +01:00
beb3062dc5 Examples: OpenGL: Fix to be able to run on ES 2.0 / WebGL 1.0. [@rmitton, @gabrielcuvillier] 2019-03-03 23:34:28 +01:00
9d1a392d7d Examples: OpenGL: Comments about versions and loaders. (#2393, #2351) 2019-03-03 23:25:51 +01:00
1c67d09c0b ColorPicker: Fix assertion when running in a collapsed window and dragging its title bar (#2389) 2019-03-01 00:06:36 +01:00
1d0b4df3d9 Misc: Asserting in NewFrame() if style.WindowMinSize is zero or smaller than (1.0f,1.0f). Internal: ImHash functions tweaks. Added InputText() to query status section. 2019-02-28 22:57:22 +01:00
f02705fbaa InputInt, InputScalar: +/- buttons now respects the natural type limits instead of overflowing or underflowing the value. 2019-02-27 18:59:17 +01:00
736d3e2654 DragScalar, InputScalar, SliderScalar: Added support for u8/s8/u16/s16 data types. We are reusing function instances for larger types to reduce code size. (#643, #320, #708, #1011) 2019-02-27 18:16:03 +01:00
525a53a86b Comments 2019-02-27 17:26:18 +01:00
ac47710db7 Internal: InputText: Tweaks to make PVS static analyzer relax a little with its false positive. 2019-02-27 16:49:55 +01:00
6de09a5e48 Renamed ColorEdit/ColorPicker's ImGuiColorEditFlags_RGB/_HSV/_HEX flags to respectively ImGuiColorEditFlags_DisplayRGB/_DisplayHSV/_DisplayHex. This is anticipation of adding new flags to ColorEdit/ColorPicker functions which would make those ambiguous. (#2384) [@haldean] 2019-02-27 16:45:58 +01:00
8a2f6866a6 add _Show prefix to color flags that control inputs, rename __InputsMask to __ShowMask
This is anticipation of changing __InputsMask to control the format of
input colors, and adding _InputRGB and _InputHSV to change how input
colors are interpreted.
2019-02-27 16:24:15 +01:00
688035b5f4 Added px_render_imgui.h (#1935) 2019-02-27 15:06:11 +01:00
cef77098ab Update README.md 2019-02-27 15:00:41 +01:00
75641926e1 Merge branch 'allegro-touch' of https://github.com/dos1/imgui into dos1-allegro-touch
# Conflicts:
#	examples/imgui_impl_allegro5.cpp
2019-02-27 14:39:41 +01:00
def723b6b6 Plot: Fixed error in 5e3a1de (#2387) 2019-02-27 14:34:11 +01:00
5e3a1de4e6 Plot: Fixed divide-by-zero in PlotLines() when passing a count of 1. (#2387) [@Lectem] 2019-02-27 14:25:37 +01:00
cf3cb7cf7e InputText: Fixed various display corruption related to swapping the underlying buffer while a input widget is active (both for writable and read-only paths). Often they would manifest when manipulating the scrollbar of a multi-line input text. 2019-02-26 12:50:44 +01:00
b7b82520b4 Internal: InputText: Minor changes (intended to have side-effect but clarify next commit, however there is rarely such a thing as zero side effect in InputText land!) 2019-02-26 12:28:27 +01:00
439f726945 InputText; Disabled rendering selection when inactive (it kinda work but I'm not sure this is desirable especially for single-line input, was not intended to be active). 2019-02-24 23:31:00 +01:00
5d7bd2309b Fixes warning caused by a missing switch/case. (#2382, #2381) 2019-02-24 23:19:36 +01:00
c3ea1748dc Fix -Wconversion warning (#2379)
The warning was caused by implicit conversion from pointer type which
NULL has to non-pointer type, e.g. if ImTextureID is long int
2019-02-24 18:35:52 +01:00
6f80179a1d InputText: Fixed deactivated but-last-active InputText instance holding on displaying the last active version of the text and not reflecting change in the source. Fix/amend 2e9a175. [+test] 2019-02-23 17:04:54 +01:00
6cbf4b8121 Fixed uninitialized variable (leading to asserts in the docking branch). (#2376, #2371) 2019-02-23 17:00:59 +01:00
9558e327d2 Log/Capture: Fixed extraneous leading carriage return. Fixed an issue when empty string on a new line would not emit a carriage return. 2019-02-23 16:22:55 +01:00
cd67d4d3c1 Log/Capture: Fixed LogXXX functions 'auto_open_depth' parameter being treated as an absolute tree depth instead of a relative one. Fixed CollapsingHeader trailing ascii representation being "#" instead of "##". Minor tidying up the of code. 2019-02-23 16:07:01 +01:00
2cd7de5666 Internal: Log/Capture: Rework to add an internal LogToBuffer() function which is useful for writing automated tests. Clarified logging state by adding an enum. 2019-02-23 15:57:06 +01:00
3eba840053 Nav: Fixed a tap on AltGR (e.g. German keyboard) from navigation to the menu layer. (follow and extend on e.g #369, #370) 2019-02-23 14:50:36 +01:00
9da48c16c5 TabBar: Added extra mis-usage error recovery. Past the assert, common mis-usage don't lead to hard crashes any more, facilitating integration with scripting languages. (#1651) 2019-02-22 12:27:41 +01:00
0f83145aa8 TabBar: Fixed a crash when using BeginTabBar() recursively (didn't affect docking). (#2371)
Added ImPool::Contains() helper.
2019-02-22 12:24:27 +01:00
f988618ebe Internal: InputText: Tweaks (including a large indentation change, compare ignoring space) to make next commit more digestible. 2019-02-21 23:06:26 +01:00
be593f2c16 Internal: InputText: refactor the flow to easily decorrelate rendering of selection vs cursor, which would allow us to render selection on inactive items, and generally makes the code clearer. + Some renaming. 2019-02-21 22:56:09 +01:00
332f8f2462 Internal: InputText: Made clipboard copy/cut use its own temporary buffer (like paste) so we can guarantee that TempBuffer if not altered and can be preserved. Renamed TempBufferA to TextA to celebrate this. 2019-02-21 19:55:37 +01:00
81a8730022 Internal: InputText: Renamed is_editable to !is_readonly, Hopefully more explicit. Renamed internal member. Shuffled some code. Added comments, assert (_will_ trigger on !readonly > readonly edge, old bug). 2019-02-21 19:55:36 +01:00
cc3be5d428 InputText: Fixed an edge case crash that would happen if another widget sharing the same ID is being swapped with an InputText that has yet to be activated. 2019-02-21 19:55:36 +01:00
2e9a175057 Internal: InputText: Refactor to clarify access pattern to the InputTextState (we are now accessing via a pointer which can be NULL, shortened its name while we are at it) + added an assert to track an issue that existed already before. 2019-02-21 19:55:36 +01:00
677e64e71e Internal: InputText: Comments. Renamed internal member. Renamed ImGuiStb->ImStb. 2019-02-20 21:34:08 +01:00
79f7778e48 Moved binaries to dearimgui.org/binaries 2019-02-20 15:11:18 +01:00
2068dd509c Examples: OpenGL: Fix for OSX not supporting OpenGL 4.5, we don't try to read GL_CLIP_ORIGIN even if the OpenGL headers/loader happens to define the value. (#2366, #2186) 2019-02-20 14:31:19 +01:00
782b747a17 InputText: Renamed some local variables to clarify code. Should be a no-op functionality wise. TODO items. 2019-02-20 00:45:45 +01:00
7c51cba74f InputInt, InputFloat, InputScalar: Fix to keep the label of the +/- buttons centered when style.FramePadding.x is abnormally larger than style.FramePadding.y. Since the buttons are meant to be square (to align with e.g. color button) we always use FramePadding.y. (#2367) 2019-02-20 00:20:11 +01:00
257f5d204e Version 1.69 WIP 2019-02-20 00:11:36 +01:00
93b06e6e7c Internal: Changed Scrollbar() signature. Using GetScrollbarID() in InputTextMultiline().
Removed multiple semi-colons (#2368)
2019-02-20 00:08:21 +01:00
91cc32379d Updated binaries (now auto-generated by a script! next step would be to slowly transition all this stuff into a public repo) 2019-02-19 20:27:47 +01:00
d0c98bf880 Examples: VS: Made project paths independant of SolutionDir so they can be built aside from the solution. 2019-02-19 20:13:06 +01:00
77833003ff Fixed unused argument warning when compiling with IM_ASERT() evaluating to an empty macro. 2019-02-19 17:32:14 +01:00
3c15dffc94 Version 1.68 2019-02-19 12:50:46 +01:00
f5bf6e38d2 Font: Fixed assert when specifying duplicate/overlapping ranges within a same font. (#2353, #2233) 2019-02-18 12:11:46 +01:00
db40699990 imgui_freeetype: Updated suggested test code. 2019-02-18 12:08:19 +01:00
d972533d09 Examples: Vulkan: Rewrote scissor processing to match other examples more closely. Removed extraneous +1 of scissor extent height. 2019-02-16 12:33:38 +01:00
dd14adc731 Examples: Vulkan: Support draw_data->FramebufferScale correctly matching a79785c for on Metal/GL2/GL3. (#2306, #1676) 2019-02-16 12:32:44 +01:00
f977871854 ImFont: Minor adjustment to the structure.
Examples: Removed unused variable.
2019-02-15 18:56:08 +01:00
76dbff37cd Selectable: Tweaks for #2347 (demo, changelog, member position) 2019-02-14 20:29:50 +01:00
b277cfffc8 Selectable: add support for specifying text alignment on selectables (#2347)
Adds a style variable to Selectable that allows clients to specify the
text alignment within Selectables, adds a section in the demo to
demonstrate selectable text alignment, and a pair of sliders in the
style editor to change selectable alignment on the fly.

In terms of implementation, this one is extremely simple: Selectable was
already calling an API that supports text alignment, but had hard-coded
it to top-left. This changes that to just pass the style variable
straight through to RenderTextClipped. Backwards-compatibility is
preserved by defaulting the text_align parameter to (0, 0), i.e.,
top-left.

This also fixes a bug with selectable text rendering that caused
right-aligned text in a selectable to be clipped incorrectly, because
the wrong clipping rectangle was being used.
2019-02-14 19:38:57 +01:00
93d1179805 Examples: Extracted gamepad code into ImGui_ImplGlfw_UpdateGamepads(). Renamed matching Win32 function for consistency.
Added more link to nothing's oversample document. Spacing bits.
2019-02-14 19:29:09 +01:00
3c07ec6a61 Made it illegal/assert when io.DisplayTime == 0.0f (with an exception for the first frame).
Causing too many subtle side-effect, e.g. IsNavInputPressed() would return true multiple times in a row.
2019-02-14 17:14:29 +01:00
2206df9e7a Demo: Added Auto-Scroll option in Log/Console. Comments. Removed some ImColor() uses. 2019-02-14 14:08:36 +01:00
8522a4bbea Fixed Clang warning ("multi-line comment"). XCode also also "space between \ and carriage return". Perhaps it would work with 2 spaces? Adding a dot for now.. 2019-02-14 14:08:00 +01:00
0236bc246f Scrollbar: Fade out and disable interaction when too small, in order to facilitate using the resize grab on very small window, as well as reducing visual noise/overlap. (+1 squashed commits)
Internals: Added GetScrollbarID(). (#1185)
2019-02-14 14:07:59 +01:00
57a586b4f1 Font: Moved functions to internal block (not enforced). Made ConfigData pointer const. Added link to stb's notes. 2019-02-13 18:21:21 +01:00
fcdf704dfa Changelog: Added changelog from 1.40 to 1.47 (pasted from the Releases section) + some wrapping. 2019-02-13 14:55:28 +01:00
cbc8e57410 Update README.md - change imgui-sfml link (#2345)
Changed link from https://github.com/EliasD/sfml to https://github.com/eliasdaler/sfml (no redirect + more reliable)
2019-02-13 11:50:14 +01:00
417cf2237f Font: Fixed high-level ImGui::CalcTextSize() used by most widgets from erroneously subtracting 1.0f*scale to calculated text width. Among noticeable side-effects, it would make sequences of repeated Text/SameLine calls not align the same as a single call, and create mismatch between high-level size calculation and those performed with the lower-level ImDrawList api. (#792) 2019-02-12 22:43:56 +01:00
0640b6e67c Shallow tweaks 2019-02-12 22:15:19 +01:00
cc80d8e118 Examples: Metal: Compilation fix. 2019-02-12 10:30:09 +01:00
169e3981fd Examples: OpenGL2: Added #define GL_SILENCE_DEPRECATION to cope with newer XCode warnings. 2019-02-11 19:09:54 +01:00
d16dbc5b87 Examples: SDL: Using the SDL_WINDOW_ALLOW_HIGHDPI flag. (#2306, #1676) [@rasky] 2019-02-11 18:52:08 +01:00
a79785c0b9 ImDrawData: Added FramebufferScale field (currently a copy of the value from io.DisplayFramebufferScale).
This is to allow render functions being written without pulling any data from ImGuiIO, allowing incoming multi-viewport feature to behave on Retina display and with multiple displays. If you are not using a custom binding, please update your render function code ahead of time, and use draw_data->FramebufferScale instead of io.DisplayFramebufferScale. (#2306, #1676)
Examples: Metal, OpenGL2, OpenGL3: Fixed offsetting of clipping rectangle with ImDrawData::DisplayPos != (0,0) when the display frame-buffer scale scale is not (1,1). While this doesn't make a difference when using master branch, this is effectively fixing support for multi-viewport with Mac Retina Displays on those examples. (#2306) Also using ImDrawData::FramebufferScale instead of io.DisplayFramebufferScale.
Examples: Clarified the use the ImDrawData::DisplayPos to offset clipping rectangles.
2019-02-11 18:52:08 +01:00
ef7940699e Examples: Metal: Removed unnecessary loop. Fixed OSX Clang warning in imstb_truetype. (#1929, #1873) 2019-02-11 17:38:34 +01:00
4b41d3b280 ImFont: Rearranged members toward an optimal CalcTextSize() loop. Removed comments from destructor. Made constructor more explicit. 2019-02-09 15:54:47 +01:00
539f69b950 Updated STB libraries to latest (drift has been reduced with nothings/stb as most of our changes were merged). Using [DEAR IMGUI] markers when changed. 2019-02-08 15:24:59 +01:00
00c637961b Demo: Font selector allow selecting fonts with same debug name. (#2332) 2019-02-08 14:59:09 +01:00
afc36cf802 Window: Fixed initial width of collapsed windows not taking account of contents width (broken in 1.67). (#2336, #176) 2019-02-08 14:34:42 +01:00
1b63ded8fa Tabs: Fixed border (when enabled) so it is aligned correctly mid-pixel and appears as bright as other borders. 2019-02-07 12:07:53 +01:00
29d38b59d0 ListBox/InputTextMultiline: Better optimized when clipped / non-visible. 2019-02-06 14:46:14 +01:00
62084aac0f DragScalarN, SliderScalarN, InputScalarN: Removed unnecessary string id after the integer PushID() calls. 2019-02-06 14:39:00 +01:00
f366828dd2 Minor tweaks to reduce false positive of PVS Studio static analyzer. 2019-02-06 13:16:52 +01:00
5bdc7d7a6f Menus: Tweaked horizontal overlap between parent and child menu (to help convey relative depth) from using style.ItemSpacing.x to style.ItemInnerSpacing.x, the later being expected to be smaller. (#1086) 2019-02-06 12:32:10 +01:00
e3dd95d335 Added IsItemActivated() as an extension to the IsItemDeactivated/IsItemDeactivatedAfterEdit functions which are useful to implement variety of undo patterns. (#820, #956, #1875) 2019-02-06 11:52:42 +01:00
c59611a3b3 InputText: Fixed redo buffer exhaustion handling (rare) which could corrupt the undo character buffer. (#2333) 2019-02-05 23:38:57 +01:00
97ed97b8ce Plot: Register an ID to take the click the same way as other framed widgets. Set HoveredId in the FramePadding zone (between inner_bb and frame_bb). 2019-02-05 21:17:04 +01:00
cef4e086ba Internals: Selectable: Fixed rendering width miscalculation when starting pos is not line start pos, which would generally be unnoticeable. Could affect group lock X with a smaller SetCursorPos value but that's unlikely to be used. 2019-02-05 21:17:00 +01:00
b8c24aff4c Internals: EndGroup: Removed unnecesary parameter to ItemSize() 2019-02-05 21:16:54 +01:00
521470b3cd Internals: Removed unnecessary code. 2019-02-05 21:16:32 +01:00
5a95c77388 Merge branch 'master' of https://github.com/ocornut/imgui 2019-02-05 13:53:09 +01:00
b980e0077a Tabs: Moved Tab List Popup to left-side to match docking button. Highlight selected tab. (#261, #351) 2019-02-05 13:39:48 +01:00
d38f4dc143 Tabs: Non-docking tab bars are storing names to allow tab list button + whole style scaling. Added ImGuiTabBarFlags_TabListPopupButton flag to show a popup button on manual tab bars. Locking FramePadding for the scope of a tab-bar to avoid sheering/clipping of tab item. Made scaling of tab ellipsis less awkward. (#261, #351) 2019-02-05 13:23:44 +01:00
d93e3c17fc ImGuiTextBuffer: Fix size() to allow using ImGuiTextBuffer with resize(0) patterns. 2019-02-05 13:16:23 +01:00
65c972e9e4 Update README.md 2019-02-05 11:45:19 +01:00
f7c879eb60 RadioButton: Fixed label horizontal alignment to precisely match Checkbox(). + Internals: Checkbox, RadioButton: Single call to ItemSize() for flow layout purpose. 2019-02-04 23:34:32 +01:00
0b05ba18df Internals: DragScalar, SliderScalar: Calling ItemSize before ItemAdd as with every other widgets so we can more easily rearrange the signature of ItemXXX functions (toward allowing non-rounded sizes for scaling and flow layout). 2019-02-04 23:34:27 +01:00
8e44aacc8e Fonts: Fixed crash if FontGlobalScale is zero. Correctly debug naming default font if not 13 px. Demo: Moved PopupRounding along with other rounding values. Metrics: Displaying indexes with idx to be correct / less misleading. 2019-02-04 23:34:20 +01:00
c23a19c26f Internals: Exposed internal SetWindowPos to imgui_internal.h (for imgui-test) 2019-02-03 17:29:51 +01:00
ac6d474103 Removed io.DisplayVisibleMin/DisplayVisibleMax (which were marked obsolete and removed from viewport/docking branch already). 2019-02-01 16:37:07 +01:00
5fc6899dc2 Examples: OpenGL3: Using GLSL 4.10 shaders for any GLSL version over 410 (e.g. 430, 450). (#2329) [@BrutPitt] 2019-02-01 15:13:54 +01:00
5cb7040f66 Internals: Tracking dummy select scope id (currently always zero) to facilitate merging of the range_select branch. (#1861) 2019-02-01 12:14:38 +01:00
d5945aa25b Internals: Minor changes to TreeNodeBehavior() and Selectable() for the benefit of fhe range_select branch. (#1861) 2019-02-01 12:14:38 +01:00
0d4a2a2cd0 Internals: Track ActiveIdHasBeenPressed (similar to ActiveIdHasBeenEdited). This is currently mostly for the benefit of the range_select branch. (#1861) 2019-02-01 12:14:37 +01:00
52a9f8bd3e Merged from Docking branch: Various small changes, comments, typos fixes, moved blocks. To reduce overall drift. Should be no-op. 2019-02-01 10:26:08 +01:00
699e945a82 Merged from Docking branch: non-const ImVec2[] operator. 2019-02-01 10:22:46 +01:00
2d363fa315 Fixed doc typo (#2326) 2019-01-31 14:19:15 +01:00
16c0a0217c Updating supporter list. 2019-01-31 13:45:46 +01:00
1fb57c97c6 Internals: InputScalarAsWidgetReplacement: Fixed seemingly unnecessary calling of SetActiveID/SetHoveredID every frame, which in turns allow us to remove the g.ActiveIdAllow/Block settings duplicated. 2019-01-30 15:41:20 +01:00
fb4f1ff7f6 InputText: Fixed a bug where ESCAPE would be first captured by the Keyboard Navigation code. (#2321, #787) 2019-01-30 15:16:09 +01:00
158995f271 InputText: Fixed a bug where ESCAPE would not restore the initial value in all situations. (#2321) [@relick] 2019-01-30 13:15:14 +01:00
0a233a505d imgui-test: Added extra item info callbacks. Using nav_bb for interactions when possible. Comments, Demo tweaks. 2019-01-30 12:53:01 +01:00
aacf993ee1 ImStrncpy: Fixed -Wstringop-truncation warning on GCC8 (#2323) 2019-01-30 10:19:40 +01:00
ed240c910b Demo: Fixed "Log" demo not initializing properly, leading to the first line not showing before a Clear. (#2318) [@bluescan] 2019-01-29 14:36:55 +01:00
8a4422b2fa Fixed CloseCurrentPopup() on a child-menu of a modal incorrectly closing the modal. (#2308) 2019-01-27 23:54:17 +01:00
13ca2fe845 Silence XCode static analysis false positive (#2309) 2019-01-27 23:30:44 +01:00
8a605354ef Replacing one of the third-party Python bindings. (#2312)
Removing the unmaintained CyImGui (only 7 commits, last one made in 2015) and replacing it with bimpy.
2019-01-27 21:59:48 +01:00
b26ac92a12 Revert "Added PushID(size_t sz) helper (may not be useful/meaningful for non C/C++ languages)."
This reverts commit 20bc06af70.
2019-01-27 16:43:56 +01:00
f56d9b74cc Nav: Removed unnecessary test (always failing). 2019-01-27 16:37:02 +01:00
4e8e177cac Persistently fixing some PVS-Studio static analyzer false positive warnings. 2019-01-27 16:35:48 +01:00
ee3b4f2bf1 Using IM_UNUSED() macro. 2019-01-27 16:23:23 +01:00
c3c2cd1e82 Fix various XCode and PVS-Studio static analyzer warnings (#2309) 2019-01-27 16:18:23 +01:00
20bc06af70 Added PushID(size_t sz) helper (may not be useful/meaningful for non C/C++ languages). 2019-01-27 16:18:23 +01:00
e55678adec Update README.md (changed e-mail address) 2019-01-24 18:31:31 +01:00
a8277ca873 Reoder Python bindings 2019-01-23 20:04:08 +01:00
c362a96a3f When resizing from an edge, the border is more visible and better follow the rounded corners. Border rendering moved to RenderOuterBorders so it can be called in a different order for docking. (#1495, #822) 2019-01-23 19:21:25 +01:00
ab9cd44c89 Examples: DirectX9: Fix Clang warning. 2019-01-22 13:47:15 +01:00
f14f93ef6e Fixed range-version of PushID() and GetID() not honoring the ### operator to restart from the seed value. 2019-01-21 16:50:27 +01:00
28901dd104 Internals: Tweaks. Comments about PushID/GetID public function. 2019-01-21 16:50:27 +01:00
f994b8aab8 ImHash: Moved crc32 table out of the function so it can be shared, also avoid cases were compiler tries to makes its initialization thread-safe. 2019-01-21 16:50:27 +01:00
1e4cf67a53 avoid floating point exception when _EM_OVERFLOW is enabled (#2303) 2019-01-21 16:43:07 +01:00
ea7206fd4f Fixed using imgui_freetype.cpp in unity builds. (#2302) 2019-01-21 13:58:29 +01:00
54ba8a643e Removed trailing spaces from text files. (#2038, #2299) 2019-01-20 22:23:29 +01:00
00ffdb9fa9 ImGuiTextBuffer: Added append() function (unformatted). 2019-01-20 22:21:26 +01:00
259f3c78a2 Examples: OpenGL2: Added (yet another) comment/instruction against using opengl2 with modern OpenGL. (#2297) 2019-01-20 18:13:39 +01:00
2c38b32db1 Removed trailing spaces (#2038, #2299) 2019-01-20 17:56:17 +01:00
e837099b67 Update for stb_ files. (#2038) 2019-01-20 17:51:51 +01:00
f94ba546ba Added checks for "zero-as-null-pointer-constant" warnings for older Clang (#2299, followup to #2277) 2019-01-20 17:46:00 +01:00
8a63c72ac4 Fix the year for screenshot gallery part 7 and 8 links (#2298) 2019-01-19 20:45:17 +01:00
fcd61e0c59 Comments about DLL boundaries and using TLS variables for GImGui. (#2292) 2019-01-18 23:04:45 +01:00
92d29531fa Qt links 2019-01-18 11:34:25 +01:00
295ada0364 Examples: Win32: Using wc.lpszClassName instead of duplicating the literal. + tweak README format. 2019-01-17 18:30:15 +01:00
b8020032f9 Examples: Win32: Added support for mouse buttons 4 and 5 via WM_XBUTTON* messages. (#2264) 2019-01-17 16:55:23 +01:00
bebb07f12d ImFontAtlas: Added 0x2000-0x206F general punctuation range to default ChineseFull/ChineseSimplifiedCommon ranges. (#2093) 2019-01-17 16:48:11 +01:00
872477548b Examples: Win32: Using IsChild() to be compatible with windows created within a parent. (#1951, #2087, #2156, #2232) 2019-01-17 11:45:32 +01:00
14c40242db Examples: DirectX9: Explicitly disable fog (D3DRS_FOGENABLE) before drawing in case user state has it set. (#2288, #2290) 2019-01-17 11:39:40 +01:00
f2c92808f8 EditorConfig: Further tweaks (#2038) 2019-01-16 22:02:42 +01:00
83810039d1 Add editor config for 4 spaces instead of tab. 2019-01-16 22:00:33 +01:00
8cbb91261e ImDrawList: Fixed AddCircle(), AddCircleFilled() angle step being off, which was visible when drawing a "circle" with a small number of segments (e.g. an hexagon). (#2287) [@baktery]
+ Demo tweaks
2019-01-16 17:47:49 +01:00
06aaf23877 Various tweaks and fixes as suggested by PVS Studio (thanks PVS Studio!) 2019-01-16 16:10:51 +01:00
882f1bc135 Examples: DirectX12: Targeting 10.0.14393.0 instead of 10.0.16299.0 (available on AppVeyor, and higher version doesn't seem necessary). 2019-01-16 15:10:31 +01:00
09f1cb642b FreeType: Minor tweaks previous commit (#2285) 2019-01-15 21:50:43 +01:00
daac9c7559 By default ImGuiFreeType will use ImGui::MemAlloc()/MemFree().
ImGuiFreeType::SetAllocatorFunctions() can be used to specify custom allocator.
2019-01-15 21:47:46 +01:00
f435aa193b Examples: Win32: Added support for XInput games (if ImGuiConfigFlags_NavEnableGamepad is enabled). 2019-01-15 21:19:02 +01:00
133f112af0 Examples: Win32: Using GetForegroundWindow() instead of GetActiveWindow() to be compatible with windows created in a different thread. (#1951, #2087, #2156, #2232) [many people] 2019-01-15 20:27:32 +01:00
95ee99e6aa Version 1.68 WIP 2019-01-15 20:19:05 +01:00
b2e7a3806a Examples: Allegro5: Add touchscreen support 2018-11-30 16:54:30 +01:00
109 changed files with 10150 additions and 5407 deletions

20
.editorconfig Normal file
View File

@ -0,0 +1,20 @@
# editorconfig.org
# top-most EditorConfig file
root = true
# Default settings:
# Use 4 spaces as indentation
[*]
indent_style = space
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true
[imstb_*]
indent_size = 3
trim_trailing_whitespace = false
[Makefile]
indent_style = tab
indent_size = 4

View File

@ -30,7 +30,318 @@ HOW TO UPDATE?
----------------------------------------------------------------------- -----------------------------------------------------------------------
VERSION 1.67 (In Progress) VERSION 1.71 (Released 2019-06-12)
-----------------------------------------------------------------------
Breaking Changes:
- IO: changed AddInputCharacter(unsigned short c) signature to AddInputCharacter(unsigned int c).
- Renamed SetNextTreeNodeOpen() to SetNextItemOpen(). Kept inline redirection function (will obsolete).
- Window: rendering of child windows outer decorations (e.g. bg color, border, scrollbars) is now
performed as part of their parent window, avoiding the creation of an extraneous draw commands.
If you have overlapping child windows with decorations, and relied on their relative z-order to be
mapped to submission their order, this will affect your rendering. The optimization is disabled
if the parent window has no visual output because it appears to be the most common situation leading
to the creation of overlapping child windows. Please reach out if you are affected by this change!
Other Changes:
- Window: clarified behavior of SetNextWindowContentSize(). Content size is defined as the size available
after removal of WindowPadding on each sides. So SetNextWindowContentSize(ImVec2(100,100)) + auto-resize
will always allow submitting a 100x100 item without creating a scrollbar, regarding of WindowPadding.
The exact meaning of ContentSize for decorated windows was previously ill-defined.
- Window: Fixed auto-resize with AlwaysVerticalScrollbar or AlwaysHorizontalScrollbar flags.
- Window: Fixed one case where auto-resize by double-clicking the resize grip would make either scrollbar
appear for a single frame after the resize.
- Separator: Revert 1.70 "Declare its thickness (1.0f) to the layout" change. It's not incorrect
but it breaks existing some layout patterns. Will return back to it when we expose Separator flags.
- Fixed InputScalar, InputScalarN, SliderScalarN, DragScalarN with non-visible label from inserting
style.ItemInnerSpacing.x worth of trailing spacing.
- Fixed InputFloatX, SliderFloatX, DragFloatX functions erroneously reporting IsItemEdited() multiple
times when the text input doesn't match the formatted output value (e.g. input "1" shows "1.000").
It wasn't much of a problem because we typically use the return value instead of IsItemEdited() here.
- Fixed uses of IsItemDeactivated(), IsItemDeactivatedAfterEdit() on multi-components widgets and
after EndGroup(). (#2550, #1875)
- Fixed crash when appending with BeginMainMenuBar() more than once and no other window are showing. (#2567)
- ColorEdit: Fixed the color picker popup only displaying inputs as HSV instead of showing multiple
options. (#2587, broken in 1.69 by #2384).
- CollapsingHeader: Better clipping when a close button is enabled and it overlaps the label. (#600)
- Scrollbar: Minor bounding box adjustment to cope with various border size.
- Scrollbar, Style: Changed default style.ScrollbarSize from 16 to 14.
- Combo: Fixed rounding not applying with the ImGuiComboFlags_NoArrowButton flag. (#2607) [@DucaRii]
- Nav: Fixed gamepad/keyboard moving of window affecting contents size incorrectly, sometimes leading
to scrollbars appearing during the movement.
- Nav: Fixed rare crash when e.g. releasing Alt-key while focusing a window with a menu at the same
frame as clearing the focus. This was in most noticeable in back-ends such as Glfw and SDL which
emits key release events when focusing another viewport, leading to Alt+clicking on void on another
viewport triggering the issue. (#2609)
- TreeNode, CollapsingHeader: Fixed highlight frame not covering horizontal area fully when using
horizontal scrolling. (#2211, #2579)
- TabBar: Fixed BeginTabBar() within a window with horizontal scrolling from creating a feedback
loop with the horizontal contents size.
- Columns: Fixed Columns() within a window with horizontal scrolling from not covering the full
horizontal area (previously only worked with an explicit contents size). (#125)
- Columns: Fixed Separator from creating an extraneous draw command. (#125)
- Columns: Fixed Selectable with SpanAllColumns flag from creating an extraneous draw command. (#125)
- Style: Added style.WindowMenuButtonPosition (left/right, defaults to ImGuiDir_Left) to move the
collapsing/docking button to the other side of the title bar.
- Style: Made window close button cross slightly smaller.
- Log/Capture: Fixed BeginTabItem() label not being included in a text log/capture.
- ImDrawList: Added ImDrawCmd::VtxOffset value to support large meshes (64k+ vertices) using 16-bits indices.
The renderer back-end needs to set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset' to enable
this, and honor the ImDrawCmd::VtxOffset field. Otherwise the value will always be zero.
This has the advantage of preserving smaller index buffers and allowing to execute on hardware that do not
support 32-bits indices. Most examples back-ends have been modified to support the VtxOffset field.
- ImDrawList: Added ImDrawCmd::IdxOffset value, equivalent to summing element count for each draw command.
This is provided for convenience and consistency with VtxOffset.
- ImDrawCallback: Allow to override the signature of ImDrawCallback by #define-ing it. This is meant to
facilitate custom rendering back-ends passing local render-specific data to the draw callback.
- ImFontAtlas: FreeType: Added RasterizerFlags::Monochrome flag to disable font anti-aliasing. Combine
with RasterizerFlags::MonoHinting for best results. (#2545) [@HolyBlackCat]
- ImFontGlyphRangesBuilder: Fixed unnecessarily over-sized buffer, which incidentally was also not
fully cleared. Fixed edge-case overflow when adding character 0xFFFF. (#2568). [@NIKE3500]
- Demo: Added full "Dear ImGui" prefix to the title of "Dear ImGui Demo" and "Dear ImGui Metrics" windows.
- Backends: Add native Mac clipboard copy/paste default implementation in core library to match what we are
dealing with Win32, and to facilitate integration in custom engines. (#2546) [@andrewwillmott]
- Backends: OSX: imgui_impl_osx: Added mouse cursor support. (#2585, #1873) [@actboy168]
- Examples/Backends: DirectX9/10/11/12, Metal, Vulkan, OpenGL3 (Desktop GL only): Added support for large meshes
(64k+ vertices) with 16-bits indices, enable 'ImGuiBackendFlags_RendererHasVtxOffset' in those back-ends.
- Examples/Backends: Don't filter characters under 0x10000 before calling io.AddInputCharacter(),
the filtering is done in io.AddInputCharacter() itself. This is in prevision for fuller Unicode
support. (#2538, #2541)
-----------------------------------------------------------------------
VERSION 1.70 (Released 2019-05-06)
-----------------------------------------------------------------------
Breaking Changes:
- ImDrawList: Improved algorithm for mitre joints on thick lines, preserving correct thickness
up to 90 degrees angles (e.g. rectangles). If you have custom rendering using thick lines,
they will appear a little thicker now. (#2518) [@rmitton]
- Obsoleted GetContentRegionAvailWidth(), use GetContentRegionAvail().x instead.
Kept inline redirection function.
- Examples: Vulkan: Added MinImageCount/ImageCount fields in ImGui_ImplVulkan_InitInfo, required
during initialization to specify the number of in-flight image requested by swap chains.
(was previously a hard #define IMGUI_VK_QUEUED_FRAMES 2). (#2071, #1677) [@nathanvoglsam]
- Examples: Vulkan: Tidying up the demo/internals helpers (most engine/app should not rely
on them but it is possible you have!).
Other Changes:
- ImDrawList: Added ImDrawCallback_ResetRenderState, a special ImDrawList::AddCallback() value
to request the renderer back-end to reset its render state. (#2037, #1639, #2452)
Examples: Added support for ImDrawCallback_ResetRenderState in all renderer back-ends. Each
renderer code setting up initial render state has been moved to a function so it could be
called at the start of rendering and when a ResetRenderState is requested. [@ocornut, @bear24rw]
- InputText: Fixed selection background rendering one frame after the cursor movement when
first transitioning from no-selection to has-selection. (Bug in 1.69) (#2436) [@Nazg-Gul]
- InputText: Work-around for buggy standard libraries where isprint('\t') returns true. (#2467, #1336)
- InputText: Fixed ImGuiInputTextFlags_AllowTabInput leading to two tabs characters being inserted
if the back-end provided both Key and Character input. (#2467, #1336)
- Layout: Added SetNextItemWidth() helper to avoid using PushItemWidth/PopItemWidth() for single items.
Note that SetNextItemWidth() currently only affect the same subset of items as PushItemWidth(),
generally referred to as the large framed+labeled items. Because the new SetNextItemWidth()
function is explicit we may later extend its effect to more items.
- Layout: Fixed PushItemWidth(-width) for right-side alignment laying out some items (button, listbox, etc.)
with negative sizes if the 'width' argument was smaller than the available width at the time of item
submission.
- Window: Fixed window with the AlwaysAutoResize flag unnecessarily extending their hovering boundaries
by a few pixels (this is used to facilitate resizing from borders when available for a given window).
One of the noticeable minor side effect was that navigating menus would have had a tendency to disable
highlight from parent menu items earlier than necessary while approaching the child menu.
- Window: Close button is horizontally aligned with style.FramePadding.x.
- Window: Fixed contents region being off by WindowBorderSize amount on the right when scrollbar is active.
- Window: Fixed SetNextWindowSizeConstraints() with non-rounded positions making windows drift. (#2067, #2530)
- Popups: Closing a popup restores the focused/nav window in place at the time of the popup opening,
instead of restoring the window that was in the window stack at the time of the OpenPopup call. (#2517)
Among other things, this allows opening a popup while no window are focused, and pressing Escape to
clear the focus again.
- Popups: Fixed right-click from closing all popups instead of aiming at the hovered popup level
(regression in 1.67).
- Selectable: With ImGuiSelectableFlags_AllowDoubleClick doesn't return true on the mouse button release
following the double-click. Only first mouse release + second mouse down (double-click) returns true.
Likewise for internal ButtonBehavior() with both _PressedOnClickRelease | _PressedOnDoubleClick. (#2503)
- GetMouseDragDelta(): also returns the delta on the mouse button released frame. (#2419)
- GetMouseDragDelta(): verify that mouse positions are valid otherwise returns zero.
- Inputs: Also add support for horizontal scroll with Shift+Mouse Wheel. (#2424, #1463) [@LucaRood]
- PlotLines, PlotHistogram: Ignore NaN values when calculating min/max bounds. (#2485)
- Columns: Fixed boundary of clipping being off by 1 pixel within the left column. (#125)
- Separator: Declare its thickness (1.0f) to the layout, making items around separator more symmetrical.
- Combo, Slider, Scrollbar: Improve rendering in situation when there's only a few pixels available (<3 pixels).
- Nav: Fixed Drag/Slider functions going into text input mode when keyboard CTRL is held while pressing NavActivate.
- Drag and Drop: Fixed drag source with ImGuiDragDropFlags_SourceAllowNullID and null ID from receiving click
regardless of being covered by another window (it didn't honor correct hovering rules). (#2521)
- ImDrawList: Improved algorithm for mitre joints on thick lines, preserving correct thickness up to 90 degrees
angles, also faster to output. (#2518) [@rmitton]
- Misc: Added IM_MALLOC/IM_FREE macros mimicking IM_NEW/IM_DELETE so user doesn't need to revert
to using the ImGui::MemAlloc()/MemFree() calls directly.
- Misc: Made IMGUI_CHECKVERSION() macro also check for matching size of ImDrawIdx.
- Metrics: Added "Show windows rectangles" tool to visualize the different rectangles.
- Demo: Improved trees in columns demo.
- Examples: OpenGL: Added a dummy GL call + comments in ImGui_ImplOpenGL3_Init() to detect uninitialized
GL function loaders early, and help users understand what they are missing. (#2421)
- Examples: SDL: Added support for SDL_GameController gamepads (enable with ImGuiConfigFlags_NavEnableGamepad). (#2509) [@DJLink]
- Examples: Emscripten: Added Emscripten+SDL+GLES2 example. (#2494, #2492, #2351, #336) [@nicolasnoble, @redblobgames]
- Examples: Metal: Added Glfw+Metal example. (#2527) [@bear24rw]
- Examples: OpenGL3: Minor tweaks + not calling glBindBuffer more than necessary in the render loop.
- Examples: Vulkan: Fixed in-flight buffers issues when using multi-viewports. (#2461, #2348, #2378, #2097)
- Examples: Vulkan: Added missing support for 32-bit indices (#define ImDrawIdx unsigned int).
- Examples: Vulkan: Avoid passing negative coordinates to vkCmdSetScissor, which debug validation layers do not like.
- Examples: Vulkan: Added ImGui_ImplVulkan_SetMinImageCount() to change min image count at runtime. (#2071) [@nathanvoglsam]
- Examples: DirectX9: Fixed erroneous assert in ImGui_ImplDX9_InvalidateDeviceObjects(). (#2454)
- Examples: DirectX10/11/12, Allegro, Marmalade: Render functions early out when display size is zero (minimized). (#2496)
- Examples: GLUT: Fixed existing FreeGLUT example to work with regular GLUT. (#2465) [@andrewwillmott]
- Examples: GLUT: Renamed imgui_impl_freeglut.cpp/.h to imgui_impl_glut.cpp/.h. (#2465) [@andrewwillmott]
- Examples: GLUT: Made io.DeltaTime always > 0. (#2430)
- Examples: Visual Studio: Updated default platform toolset+sdk in vcproj files from v100+sdk7 (vs2010)
to v110+sdk8 (vs2012). This is mostly so we can remove reliance on DXSDK_DIR for the DX10/DX11 example,
which if existing and when switching to recent SDK ends up conflicting and creating warnings.
-----------------------------------------------------------------------
VERSION 1.69 (Released 2019-03-13)
-----------------------------------------------------------------------
Breaking Changes:
- Renamed ColorEdit/ColorPicker's ImGuiColorEditFlags_RGB/_HSV/_HEX flags to respectively
ImGuiColorEditFlags_DisplayRGB/_DisplayHSV/_DisplayHex. This is because the addition of
new flag ImGuiColorEditFlags_InputHSV makes the earlier one ambiguous.
Keep redirection enum values (will obsolete). (#2384) [@haldean]
- Renamed GetOverlayDrawList() to GetForegroundDrawList(). Kept redirection function (will obsolete). (#2391)
Other Changes:
- Added GetBackgroundDrawList() helper to quickly get access to a ImDrawList that will be rendered
behind every other windows. (#2391, #545)
- DragScalar, InputScalar, SliderScalar: Added support for u8/s8/u16/s16 data types (ImGuiDataType_S8, etc.)
We are reusing function instances of larger types to reduce code size. (#643, #320, #708, #1011)
- Added InputTextWithHint() to display a description/hint in the text box when no text
has been entered. (#2400) [@Organic-Code, @ocornut]
- Nav: Fixed a tap on AltGR (e.g. German keyboard) from navigating to the menu layer.
- Nav: Fixed Ctrl+Tab keeping active InputText() of a previous window active after the switch. (#2380)
- Fixed IsItemDeactivated()/IsItemDeactivatedAfterEdit() from not correctly returning true
when tabbing out of a focusable widget (Input/Slider/Drag) in most situations. (#2215, #1875)
- InputInt, InputFloat, InputScalar: Fix to keep the label of the +/- buttons centered when
style.FramePadding.x is abnormally larger than style.FramePadding.y. Since the buttons are
meant to be square (to align with e.g. color button) we always use FramePadding.y. (#2367)
- InputInt, InputScalar: +/- buttons now respects the natural type limits instead of
overflowing or underflowing the value.
- InputText: Fixed an edge case crash that would happen if another widget sharing the same ID
is being swapped with an InputText that has yet to be activated.
- InputText: Fixed various display corruption related to swapping the underlying buffer while
a input widget is active (both for writable and read-only paths). Often they would manifest
when manipulating the scrollbar of a multi-line input text.
- ColorEdit, ColorPicker, ColorButton: Added ImGuiColorEditFlags_InputHSV to manipulate color
values encoded as HSV (in order to avoid HSV<>RGB round trips and associated singularities).
(#2383, #2384) [@haldean]
- ColorPicker: Fixed a bug/assertion when displaying a color picker in a collapsed window
while dragging its title bar. (#2389)
- ColorEdit: Fixed tooltip not honoring the ImGuiColorEditFlags_NoAlpha contract of never
reading the 4th float in the array (value was read and discarded). (#2384) [@haldean]
- MenuItem, Selectable: Fixed disabled widget interfering with navigation (fix c2db7f63 in 1.67).
- TabBar: Fixed a crash when using many BeginTabBar() recursively (didn't affect docking). (#2371)
- TabBar: Added extra mis-usage error recovery. Past the assert, common mis-usage don't lead to
hard crashes any more, facilitating integration with scripting languages. (#1651)
- TabBar: Fixed ImGuiTabItemFlags_SetSelected being ignored if the tab is not visible (with
scrolling policy enabled) or if is currently appearing.
- TabBar: Fixed Tab tooltip code making drag and drop tooltip disappear during the frame where
the drag payload activate a tab.
- TabBar: Reworked scrolling policy (when ImGuiTabBarFlags_FittingPolicyScroll is set) to
teleport the view when aiming at a tab far away the visible section, and otherwise accelerate
the scrolling speed to cap the scrolling time to 0.3 seconds.
- Text: Fixed large Text/TextUnformatted calls not feeding their size into layout when starting
below the lower point of the current clipping rectangle. This bug has been there since v1.0!
It was hardly noticeable but would affect the scrolling range, which in turn would affect
some scrolling request functions when called during the appearing frame of a window.
- Plot: Fixed divide-by-zero in PlotLines() when passing a count of 1. (#2387) [@Lectem]
- Log/Capture: Fixed LogXXX functions emitting extraneous leading carriage return.
- Log/Capture: Fixed an issue when empty string on a new line would not emit a carriage return.
- Log/Capture: Fixed LogXXX functions 'auto_open_depth' parameter being treated as an absolute
tree depth instead of a relative one.
- Log/Capture: Fixed CollapsingHeader trailing ascii representation being "#" instead of "##".
- ImFont: Added GetGlyphRangesVietnamese() helper. (#2403)
- Misc: Asserting in NewFrame() if style.WindowMinSize is zero or smaller than (1.0f,1.0f).
- Demo: Using GetBackgroundDrawList() and GetForegroundDrawList() in "Custom Rendering" demo.
- Demo: InputText: Demonstrating use of ImGuiInputTextFlags_CallbackResize. (#2006, #1443, #1008).
- Examples: GLFW, SDL: Preserve DisplayFramebufferScale when main viewport is minimized.
(This is particularly useful for the viewport branch because we are not supporting per-viewport
frame-buffer scale. It fixes windows not refreshing when main viewport is minimized.) (#2416)
- Examples: OpenGL: Fix to be able to run on ES 2.0 / WebGL 1.0. [@rmitton, @gabrielcuvillier]
- Examples: OpenGL: Fix for OSX not supporting OpenGL 4.5, we don't try to read GL_CLIP_ORIGIN
even if the OpenGL headers/loader happens to define the value. (#2366, #2186)
- Examples: Allegro: Added support for touch events (emulating mouse). (#2219) [@dos1]
- Examples: DirectX9: Minor changes to match the other DirectX examples more closely. (#2394)
-----------------------------------------------------------------------
VERSION 1.68 (Released 2019-02-19)
-----------------------------------------------------------------------
Breaking Changes:
- Removed io.DisplayVisibleMin/DisplayVisibleMax (which were marked obsolete and removed from viewport/docking branch already).
- Made it illegal/assert when io.DisplayTime == 0.0f (with an exception for the first frame).
If for some reason your time step calculation gives you a zero value, replace it with a dummy small value!
Other Changes:
- Added .editorconfig file for text editors to standardize using spaces. (#2038) [@kudaba]
- ImDrawData: Added FramebufferScale field (currently a copy of the value from io.DisplayFramebufferScale).
This is to allow render functions being written without pulling any data from ImGuiIO, allowing incoming
multi-viewport feature to behave on Retina display and with multiple displays.
If you are not using a custom binding, please update your render function code ahead of time,
and use draw_data->FramebufferScale instead of io.DisplayFramebufferScale. (#2306, #1676)
- Added IsItemActivated() as an extension to the IsItemDeactivated/IsItemDeactivatedAfterEdit functions
which are useful to implement variety of undo patterns. (#820, #956, #1875)
- InputText: Fixed a bug where ESCAPE would not restore the initial value in all situations. (#2321) [@relick]
- InputText: Fixed a bug where ESCAPE would be first captured by the Keyboard Navigation code. (#2321, #787)
- InputText: Fixed redo buffer exhaustion handling (rare) which could corrupt the undo character buffer. (#2333)
The way the redo/undo buffers work would have made it generally unnoticeable to the user.
- Fixed range-version of PushID() and GetID() not honoring the ### operator to restart from the seed value.
- Fixed CloseCurrentPopup() on a child-menu of a modal incorrectly closing the modal. (#2308)
- Tabs: Added ImGuiTabBarFlags_TabListPopupButton flag to show a popup button on manual tab bars. (#261, #351)
- Tabs: Removed ImGuiTabBarFlags_NoTabListPopupButton which was available in 1.67 but actually had zero use.
- Tabs: Fixed a minor clipping glitch when changing style's FramePadding from frame to frame.
- Tabs: Fixed border (when enabled) so it is aligned correctly mid-pixel and appears as bright as other borders.
- Style, Selectable: Added ImGuiStyle::SelectableTextAlign and ImGuiStyleVar_SelectableTextAlign. (#2347) [@haldean]
- Menus: Tweaked horizontal overlap between parent and child menu (to help convey relative depth)
from using style.ItemSpacing.x to style.ItemInnerSpacing.x, the later being expected to be smaller. (#1086)
- RadioButton: Fixed label horizontal alignment to precisely match Checkbox().
- Window: When resizing from an edge, the border is more visible and better follow the rounded corners.
- Window: Fixed initial width of collapsed windows not taking account of contents width (broken in 1.67). (#2336, #176)
- Scrollbar: Fade out and disable interaction when too small, in order to facilitate using the resize grab on very
small window, as well as reducing visual noise/overlap.
- ListBox: Better optimized when clipped / non-visible.
- InputTextMultiline: Better optimized when clipped / non-visible.
- Font: Fixed high-level ImGui::CalcTextSize() used by most widgets from erroneously subtracting 1.0f*scale to
calculated text width. Among noticeable side-effects, it would make sequences of repeated Text/SameLine calls
not align the same as a single call, and create mismatch between high-level size calculation and those performed
with the lower-level ImDrawList api. (#792) [@SlNPacifist]
- Font: Fixed building atlas when specifying duplicate/overlapping ranges within a same font. (#2353, #2233)
- ImDrawList: Fixed AddCircle(), AddCircleFilled() angle step being off, which was visible when drawing a "circle"
with a small number of segments (e.g. an hexagon). (#2287) [@baktery]
- ImGuiTextBuffer: Added append() function (unformatted).
- ImFontAtlas: Added 0x2000-0x206F general punctuation range to default ChineseFull/ChineseSimplifiedCommon ranges. (#2093)
- ImFontAtlas: FreeType: Added support for imgui allocators + custom FreeType only SetAllocatorFunctions. (#2285) [@Vuhdo]
- ImFontAtlas: FreeType: Fixed using imgui_freetype.cpp in unity builds. (#2302)
- Demo: Fixed "Log" demo not initializing properly, leading to the first line not showing before a Clear. (#2318) [@bluescan]
- Demo: Added "Auto-scroll" option in Log/Console demos. (#2300) [@nicolasnoble, @ocornut]
- Examples: Metal, OpenGL2, OpenGL3, Vulkan: Fixed offsetting of clipping rectangle with ImDrawData::DisplayPos != (0,0)
when the display frame-buffer scale scale is not (1,1). While this doesn't make a difference when using master branch,
this is effectively fixing support for multi-viewport with Mac Retina Displays on those examples. (#2306) [@rasky, @ocornut]
Also using ImDrawData::FramebufferScale instead of io.DisplayFramebufferScale.
- Examples: Clarified the use the ImDrawData::DisplayPos to offset clipping rectangles.
- Examples: Win32: Using GetForegroundWindow()+IsChild() instead of GetActiveWindow() to be compatible with windows created
in a different thread or parent. (#1951, #2087, #2156, #2232) [many people]
- Examples: SDL: Using the SDL_WINDOW_ALLOW_HIGHDPI flag. (#2306, #1676) [@rasky]
- Examples: Win32: Added support for XInput gamepads (if ImGuiConfigFlags_NavEnableGamepad is enabled).
- Examples: Win32: Added support for mouse buttons 4 and 5 via WM_XBUTTON* messages. (#2264)
- Examples: DirectX9: Explicitly disable fog (D3DRS_FOGENABLE) before drawing in case user state has it set. (#2288, #2230)
- Examples: OpenGL2: Added #define GL_SILENCE_DEPRECATION to cope with newer XCode warnings.
- Examples: OpenGL3: Using GLSL 4.10 shaders for any GLSL version over 410 (e.g. 430, 450). (#2329) [@BrutPitt]
-----------------------------------------------------------------------
VERSION 1.67 (Released 2019-01-14)
----------------------------------------------------------------------- -----------------------------------------------------------------------
Breaking Changes: Breaking Changes:
@ -220,29 +531,36 @@ Changes:
Breaking Changes: Breaking Changes:
- Style: Renamed ImGuiCol_ModalWindowDarkening to ImGuiCol_ModalWindowDimBg for consistency with other features. Kept redirection enum (will obsolete). - Style: Renamed ImGuiCol_ModalWindowDarkening to ImGuiCol_ModalWindowDimBg for consistency with other features.
Kept redirection enum (will obsolete).
- Changed ImGui::GetTime() return value from float to double to avoid accumulating floating point imprecision over time. - Changed ImGui::GetTime() return value from float to double to avoid accumulating floating point imprecision over time.
- Removed per-window ImGuiWindowFlags_ResizeFromAnySide Beta flag in favor `io.ConfigResizeWindowsFromEdges=true` to enable the feature globally. (#1495) - Removed per-window ImGuiWindowFlags_ResizeFromAnySide Beta flag in favor `io.ConfigResizeWindowsFromEdges=true` to
enable the feature globally. (#1495)
The feature is not currently enabled by default because it is not satisfying enough, but will eventually be. The feature is not currently enabled by default because it is not satisfying enough, but will eventually be.
- InputText: Renamed ImGuiTextEditCallback to ImGuiInputTextCallback, ImGuiTextEditCallbackData to ImGuiInputTextCallbackData for consistency. - InputText: Renamed ImGuiTextEditCallback to ImGuiInputTextCallback, ImGuiTextEditCallbackData to ImGuiInputTextCallbackData
Kept redirection types (will obsolete). for consistency. Kept redirection types (will obsolete).
- InputText: Removed ImGuiTextEditCallbackData::ReadOnly since it is a duplication of (ImGuiTextEditCallbackData::Flags & ImGuiInputTextFlags_ReadOnly). - InputText: Removed ImGuiTextEditCallbackData::ReadOnly because it is a duplication of (::Flags & ImGuiInputTextFlags_ReadOnly).
- Renamed IsItemDeactivatedAfterChange() to IsItemDeactivatedAfterEdit() for consistency with new IsItemEdited() API. - Renamed IsItemDeactivatedAfterChange() to IsItemDeactivatedAfterEdit() for consistency with new IsItemEdited() API.
Kept redirection function (will obsolete soonish as IsItemDeactivatedAfterChange() is very recent). Kept redirection function (will obsolete soonish as IsItemDeactivatedAfterChange() is very recent).
- Renamed io.OptCursorBlink to io.ConfigCursorBlink [-> io.ConfigInputTextCursorBlink in 1.65], io.OptMacOSXBehaviors to io.ConfigMacOSXBehaviors for consistency. (#1427, #473) - Renamed io.OptCursorBlink to io.ConfigCursorBlink [-> io.ConfigInputTextCursorBlink in 1.65], io.OptMacOSXBehaviors to
io.ConfigMacOSXBehaviors for consistency. (#1427, #473)
- Removed obsolete redirection functions: CollapsingHeader() variation with 2 bools - marked obsolete in v1.49, May 2016. - Removed obsolete redirection functions: CollapsingHeader() variation with 2 bools - marked obsolete in v1.49, May 2016.
Other Changes: Other Changes:
- ArrowButton: Fixed to honor PushButtonRepeat() setting (and internals' ImGuiItemFlags_ButtonRepeat). - ArrowButton: Fixed to honor PushButtonRepeat() setting (and internals' ImGuiItemFlags_ButtonRepeat).
- ArrowButton: Setup current line text baseline so that ArrowButton() + SameLine() + Text() are aligned properly. - ArrowButton: Setup current line text baseline so that ArrowButton() + SameLine() + Text() are aligned properly.
- Nav: Added a CTRL+TAB window list and changed the highlight system accordingly. The change is motivated by upcoming Docking features. (#787) - Nav: Added a CTRL+TAB window list and changed the highlight system accordingly. The change is motivated by upcoming
Docking features. (#787)
- Nav: Made CTRL+TAB skip menus + skip the current navigation window if is has the ImGuiWindow_NoNavFocus set. (#787) - Nav: Made CTRL+TAB skip menus + skip the current navigation window if is has the ImGuiWindow_NoNavFocus set. (#787)
While it was previously possible, you won't be able to CTRL-TAB out and immediately back in a window with the ImGuiWindow_NoNavFocus flag. While it was previously possible, you won't be able to CTRL-TAB out and immediately back in a window with the
ImGuiWindow_NoNavFocus flag.
- Window: Allow menu and popups windows from ignoring the style.WindowMinSize values so short menus/popups are not padded. (#1909) - Window: Allow menu and popups windows from ignoring the style.WindowMinSize values so short menus/popups are not padded. (#1909)
- Window: Added global io.ConfigResizeWindowsFromEdges option to enable resizing windows from their edges and from the lower-left corner. (#1495) - Window: Added global io.ConfigResizeWindowsFromEdges option to enable resizing windows from their edges and from
the lower-left corner. (#1495)
- Window: Collapse button shows hovering highlight + clicking and dragging on it allows to drag the window as well. - Window: Collapse button shows hovering highlight + clicking and dragging on it allows to drag the window as well.
- Added IsItemEdited() to query if the last item modified its value (or was pressed). This is equivalent to the bool returned by most widgets. - Added IsItemEdited() to query if the last item modified its value (or was pressed). This is equivalent to the bool
returned by most widgets.
It is useful in some situation e.g. using InputText() with ImGuiInputTextFlags_EnterReturnsTrue. (#2034) It is useful in some situation e.g. using InputText() with ImGuiInputTextFlags_EnterReturnsTrue. (#2034)
- InputText: Added support for buffer size/capacity changes via the ImGuiInputTextFlags_CallbackResize flag. (#2006, #1443, #1008). - InputText: Added support for buffer size/capacity changes via the ImGuiInputTextFlags_CallbackResize flag. (#2006, #1443, #1008).
- InputText: Fixed not tracking the cursor horizontally when modifying the text buffer through a callback. - InputText: Fixed not tracking the cursor horizontally when modifying the text buffer through a callback.
@ -305,11 +623,14 @@ Other Changes:
Breaking Changes: Breaking Changes:
- TreeNodeEx(): The helper ImGuiTreeNodeFlags_CollapsingHeader flag now include ImGuiTreeNodeFlags_NoTreePushOnOpen. The flag was already set by CollapsingHeader(). - TreeNodeEx(): The helper ImGuiTreeNodeFlags_CollapsingHeader flag now include ImGuiTreeNodeFlags_NoTreePushOnOpen.
The only difference is if you were using TreeNodeEx() manually with ImGuiTreeNodeFlags_CollapsingHeader and without ImGuiTreeNodeFlags_NoTreePushOnOpen. The flag was already set by CollapsingHeader().
In this case you can remove the ImGuiTreeNodeFlags_NoTreePushOnOpen flag from your call (ImGuiTreeNodeFlags_CollapsingHeader & ~ImGuiTreeNodeFlags_NoTreePushOnOpen). (#1864) The only difference is if you were using TreeNodeEx() manually with ImGuiTreeNodeFlags_CollapsingHeader and without
ImGuiTreeNodeFlags_NoTreePushOnOpen. In this case you can remove the ImGuiTreeNodeFlags_NoTreePushOnOpen flag from
your call (ImGuiTreeNodeFlags_CollapsingHeader & ~ImGuiTreeNodeFlags_NoTreePushOnOpen). (#1864)
This also apply if you were using internal's TreeNodeBehavior() with the ImGuiTreeNodeFlags_CollapsingHeader flag directly. This also apply if you were using internal's TreeNodeBehavior() with the ImGuiTreeNodeFlags_CollapsingHeader flag directly.
- ImFontAtlas: Renamed GetGlyphRangesChinese() to GetGlyphRangesChineseFull() to distinguish new smaller variants and discourage using the full set. (#1859) - ImFontAtlas: Renamed GetGlyphRangesChinese() to GetGlyphRangesChineseFull() to distinguish new smaller variants and
discourage using the full set. (#1859)
Other Changes: Other Changes:
@ -322,12 +643,13 @@ Other Changes:
before: imgui_impl_glfw_vulkan.cpp --> after: imgui_impl_glfw.cpp + imgui_impl_vulkan.cpp before: imgui_impl_glfw_vulkan.cpp --> after: imgui_impl_glfw.cpp + imgui_impl_vulkan.cpp
before: imgui_impl_sdl_gl3.cpp --> after: imgui_impl_sdl2.cpp + imgui_impl_opengl2.cpp before: imgui_impl_sdl_gl3.cpp --> after: imgui_impl_sdl2.cpp + imgui_impl_opengl2.cpp
before: imgui_impl_sdl_gl3.cpp --> after: imgui_impl_sdl2.cpp + imgui_impl_opengl3.cpp etc. before: imgui_impl_sdl_gl3.cpp --> after: imgui_impl_sdl2.cpp + imgui_impl_opengl3.cpp etc.
- The idea is what we can now easily combine and maintain back-ends and reduce code redundancy. Individual files are smaller and more reusable. - The idea is what we can now easily combine and maintain back-ends and reduce code redundancy. Individual files are
Integration of imgui into a new/custom engine may also be easier as there is less overlap between "windowing / inputs" and "rendering" code, smaller and more reusable. Integration of imgui into a new/custom engine may also be easier as there is less overlap
so you may study or grab one half of the code and not the other. between "windowing / inputs" and "rendering" code, so you may study or grab one half of the code and not the other.
- This change was motivated by the fact that adding support for the upcoming multi-viewport feature requires more work from the Platform and Renderer - This change was motivated by the fact that adding support for the upcoming multi-viewport feature requires more work
back-ends, and the amount of redundancy across files was becoming too difficult to maintain. If you use default back-ends, you'll benefit from an from the Platform and Renderer back-ends, and the amount of redundancy across files was becoming too difficult to
easy update path to support multi-viewports later (for future ImGui 1.7x). maintain. If you use default back-ends, you'll benefit from an easy update path to support multi-viewports later
(for future ImGui 1.7x).
- This is not strictly a breaking change if you keep your old bindings, but when you'll want to fully update your bindings, - This is not strictly a breaking change if you keep your old bindings, but when you'll want to fully update your bindings,
expect to have to reshuffle a few things. expect to have to reshuffle a few things.
- Each example still has its own main.cpp which you may refer you to understand how to initialize and glue everything together. - Each example still has its own main.cpp which you may refer you to understand how to initialize and glue everything together.
@ -340,26 +662,36 @@ Other Changes:
- Nav: Added support for PageUp/PageDown (explorer-style: first aim at bottom/top most item, when scroll a page worth of contents). (#787) - Nav: Added support for PageUp/PageDown (explorer-style: first aim at bottom/top most item, when scroll a page worth of contents). (#787)
- Nav: To keep the navigated item in view we also attempt to scroll the parent window as well as the current window. (#787) - Nav: To keep the navigated item in view we also attempt to scroll the parent window as well as the current window. (#787)
- ColorEdit3, ColorEdit4, ColorButton: Added ImGuiColorEditFlags_NoDragDrop flag to disable ColorEditX as drag target and ColorButton as drag source. (#1826) - ColorEdit3, ColorEdit4, ColorButton: Added ImGuiColorEditFlags_NoDragDrop flag to disable ColorEditX as drag target and ColorButton as drag source. (#1826)
- BeginDragDropSource(): Offset tooltip position so it is off the mouse cursor, but also closer to it than regular tooltips, and not clamped by viewport. (#1739) - BeginDragDropSource(): Offset tooltip position so it is off the mouse cursor, but also closer to it than regular tooltips,
- BeginDragDropTarget(): Added ImGuiDragDropFlags_AcceptNoPreviewTooltip flag to request hiding the drag source tooltip from the target site. (#143) and not clamped by viewport. (#1739)
- BeginCombo(), BeginMainMenuBar(), BeginChildFrame(): Temporary style modification are restored at the end of BeginXXX instead of EndXXX, to not affect tooltips and child windows. - BeginDragDropTarget(): Added ImGuiDragDropFlags_AcceptNoPreviewTooltip flag to request hiding the drag source tooltip
from the target site. (#143)
- BeginCombo(), BeginMainMenuBar(), BeginChildFrame(): Temporary style modification are restored at the end of BeginXXX
instead of EndXXX, to not affect tooltips and child windows.
- Popup: Improved handling of (erroneously) repeating calls to OpenPopup() to not close the popup's child popups. (#1497, #1533, #1865). - Popup: Improved handling of (erroneously) repeating calls to OpenPopup() to not close the popup's child popups. (#1497, #1533, #1865).
- InputTextMultiline(): Fixed double navigation highlight when scrollbar is active. (#787) - InputTextMultiline(): Fixed double navigation highlight when scrollbar is active. (#787)
- InputText(): Fixed Undo corruption after pasting large amount of text (Redo will still fail when undo buffers are exhausted, but text won't be corrupted). - InputText(): Fixed Undo corruption after pasting large amount of text (Redo will still fail when undo buffers are exhausted,
but text won't be corrupted).
- SliderFloat(): When using keyboard/gamepad and a zero precision format string (e.g. "%.0f"), always step in integer units. (#1866) - SliderFloat(): When using keyboard/gamepad and a zero precision format string (e.g. "%.0f"), always step in integer units. (#1866)
- ImFontConfig: Added GlyphMinAdvanceX/GlyphMaxAdvanceX settings useful to make a font appears monospaced, particularly useful for icon fonts. (#1869) - ImFontConfig: Added GlyphMinAdvanceX/GlyphMaxAdvanceX settings useful to make a font appears monospaced, particularly useful
- ImFontAtlas: Added GetGlyphRangesChineseSimplifiedCommon() helper that returns a list of ~2500 most common Simplified Chinese characters. (#1859) [@JX-Master, @ocornut] for icon fonts. (#1869)
- ImFontAtlas: Added GetGlyphRangesChineseSimplifiedCommon() helper that returns a list of ~2500 most common Simplified Chinese
characters. (#1859) [@JX-Master, @ocornut]
- Examples: OSX: Added imgui_impl_osx.mm binding to be used along with e.g. imgui_impl_opengl2.cpp. (#281, #1870) [@pagghiu, @itamago, @ocornut] - Examples: OSX: Added imgui_impl_osx.mm binding to be used along with e.g. imgui_impl_opengl2.cpp. (#281, #1870) [@pagghiu, @itamago, @ocornut]
- Examples: GLFW: Made it possible to Shutdown/Init the backend again (by reseting the time storage properly). (#1827) [@ice1000] - Examples: GLFW: Made it possible to Shutdown/Init the backend again (by reseting the time storage properly). (#1827) [@ice1000]
- Examples: Win32: Fixed handling of mouse wheel messages to support sub-unit scrolling messages (typically sent by track-pads). (#1874) [@zx64] - Examples: Win32: Fixed handling of mouse wheel messages to support sub-unit scrolling messages (typically sent by track-pads). (#1874) [@zx64]
- Examples: SDL+Vulkan: Added SDL+Vulkan example. - Examples: SDL+Vulkan: Added SDL+Vulkan example.
- Examples: Allegro5: Added support for ImGuiConfigFlags_NoMouseCursorChange flag. Added clipboard support. - Examples: Allegro5: Added support for ImGuiConfigFlags_NoMouseCursorChange flag. Added clipboard support.
- Examples: Allegro5: Unindexing buffers ourselves as Allegro indexed drawing primitives are buggy in the DirectX9 back-end (will be fixed in Allegro 5.2.5+). - Examples: Allegro5: Unindexing buffers ourselves as Allegro indexed drawing primitives are buggy in the DirectX9 back-end
(will be fixed in Allegro 5.2.5+).
- Examples: DirectX12: Moved the ID3D12GraphicsCommandList* parameter from ImGui_ImplDX12_NewFrame() to ImGui_ImplDX12_RenderDrawData() which makes a lots more sense. (#301) - Examples: DirectX12: Moved the ID3D12GraphicsCommandList* parameter from ImGui_ImplDX12_NewFrame() to ImGui_ImplDX12_RenderDrawData() which makes a lots more sense. (#301)
- Examples: Vulkan: Reordered parameters ImGui_ImplVulkan_RenderDrawData() to be consistent with other bindings, a good occasion since we refactored the code. - Examples: Vulkan: Reordered parameters ImGui_ImplVulkan_RenderDrawData() to be consistent with other bindings,
a good occasion since we refactored the code.
- Examples: FreeGLUT: Added FreeGLUT bindings. Added FreeGLUT+OpenGL2 example. (#801) - Examples: FreeGLUT: Added FreeGLUT bindings. Added FreeGLUT+OpenGL2 example. (#801)
- Examples: The functions in imgui_impl_xxx.cpp are prefixed with IMGUI_IMPL_API (which defaults to IMGUI_API) to facilitate some uses. (#1888) - Examples: The functions in imgui_impl_xxx.cpp are prefixed with IMGUI_IMPL_API (which defaults to IMGUI_API) to facilitate
- Examples: Fixed bindings to use ImGuiMouseCursor_COUNT instead of old name ImGuiMouseCursor_Count_ so they can compile with IMGUI_DISABLE_OBSOLETE_FUNCTIONS. (#1887) some uses. (#1888)
- Examples: Fixed bindings to use ImGuiMouseCursor_COUNT instead of old name ImGuiMouseCursor_Count_ so they can compile
with IMGUI_DISABLE_OBSOLETE_FUNCTIONS. (#1887)
- Misc: Updated stb_textedit from 1.09 + patches to 1.12 + minor patches. - Misc: Updated stb_textedit from 1.09 + patches to 1.12 + minor patches.
- Internals: PushItemFlag() flags are inherited by BeginChild(). - Internals: PushItemFlag() flags are inherited by BeginChild().
@ -370,41 +702,56 @@ Other Changes:
Breaking Changes: Breaking Changes:
- DragInt(): The default compile-time format string has been changed from "%.0f" to "%d", as we are not using integers internally any more. - DragInt(): The default compile-time format string has been changed from "%.0f" to "%d", as we are not using integers internally
If you used DragInt() with custom format strings, make sure you change them to use %d or an integer-compatible format. any more. If you used DragInt() with custom format strings, make sure you change them to use %d or an integer-compatible format.
To honor backward-compatibility, the DragInt() code will currently parse and modify format strings to replace %*f with %d, giving time to users to upgrade their code. To honor backward-compatibility, the DragInt() code will currently parse and modify format strings to replace %*f with %d,
If you have IMGUI_DISABLE_OBSOLETE_FUNCTIONS enabled, the code will instead assert! You may run a reg-exp search on your codebase for e.g. "DragInt.*%f" to you find them. giving time to users to upgrade their code.
- InputFloat(): Obsoleted InputFloat() functions taking an optional "int decimal_precision" in favor of an equivalent and more flexible "const char* format", If you have IMGUI_DISABLE_OBSOLETE_FUNCTIONS enabled, the code will instead assert! You may run a reg-exp search on your
consistent with other functions. Kept redirection functions (will obsolete). codebase for e.g. "DragInt.*%f" to you find them.
- Misc: IM_DELETE() helper function added in 1.60 doesn't set the input pointer to NULL, more consistent with standard expectation and allows passing r-values. - InputFloat(): Obsoleted InputFloat() functions taking an optional "int decimal_precision" in favor of an equivalent and more
flexible "const char* format", consistent with other functions. Kept redirection functions (will obsolete).
- Misc: IM_DELETE() helper function added in 1.60 doesn't set the input pointer to NULL, more consistent with standard
expectation and allows passing r-values.
Other Changes: Other Changes:
- Added DragScalar, DragScalarN: supports signed/unsigned, 32/64 bits, float/double data types. (#643, #320, #708, #1011) - Added DragScalar, DragScalarN: supports signed/unsigned, 32/64 bits, float/double data types. (#643, #320, #708, #1011)
- Added InputScalar, InputScalarN: supports signed/unsigned, 32/64 bits, float/double data types. (#643, #320, #708, #1011) - Added InputScalar, InputScalarN: supports signed/unsigned, 32/64 bits, float/double data types. (#643, #320, #708, #1011)
- Added SliderScalar, SliderScalarN: supports signed/unsigned, 32/64 bits, float/double data types. (#643, #320, #708, #1011) - Added SliderScalar, SliderScalarN: supports signed/unsigned, 32/64 bits, float/double data types. (#643, #320, #708, #1011)
- Window: Fixed pop-ups/tooltips/menus not honoring style.DisplaySafeAreaPadding as well as it should have (part of menus displayed outside the safe area, etc.). - Window: Fixed pop-ups/tooltips/menus not honoring style.DisplaySafeAreaPadding as well as it should have (part of menus
displayed outside the safe area, etc.).
- Window: Fixed windows using the ImGuiWindowFlags_NoSavedSettings flag from not using the same default position as other windows. (#1760) - Window: Fixed windows using the ImGuiWindowFlags_NoSavedSettings flag from not using the same default position as other windows. (#1760)
- Window: Relaxed the internal stack size checker to allow Push/Begin/Pop/.../End patterns to be used with PushStyleColor, PushStyleVar, PushFont without causing a false positive assert. (#1767) - Window: Relaxed the internal stack size checker to allow Push/Begin/Pop/.../End patterns to be used with PushStyleColor, PushStyleVar, PushFont without causing a false positive assert. (#1767)
- Window: Fixed the default proportional item width lagging by one frame on resize. - Window: Fixed the default proportional item width lagging by one frame on resize.
- Columns: Fixed a bug introduced in 1.51 where columns would affect the contents size of their container, often creating feedback loops when ImGuiWindowFlags_AlwaysAutoResize was used. (#1760) - Columns: Fixed a bug introduced in 1.51 where columns would affect the contents size of their container, often creating
feedback loops when ImGuiWindowFlags_AlwaysAutoResize was used. (#1760)
- Settings: Fixed saving an empty .ini file if CreateContext/DestroyContext are called without a single call to NewFrame(). (#1741) - Settings: Fixed saving an empty .ini file if CreateContext/DestroyContext are called without a single call to NewFrame(). (#1741)
- Settings: Added LoadIniSettingsFromDisk(), LoadIniSettingsFromMemory(), SaveIniSettingsToDisk(), SaveIniSettingsToMemory() to manually load/save .ini settings. (#923, #993) - Settings: Added LoadIniSettingsFromDisk(), LoadIniSettingsFromMemory(), SaveIniSettingsToDisk(), SaveIniSettingsToMemory()
- Settings: Added io.WantSaveIniSettings flag, which is set to notify the application that e.g. SaveIniSettingsToMemory() should be called. (#923, #993) to manually load/save .ini settings. (#923, #993)
- Scrolling: Fixed a case where using SetScrollHere(1.0f) at the bottom of a window on the same frame the window height has been growing would have the scroll clamped using the previous height. (#1804) - Settings: Added io.WantSaveIniSettings flag, which is set to notify the application that e.g. SaveIniSettingsToMemory()
- MenuBar: Made BeginMainMenuBar() honor style.DisplaySafeAreaPadding so the text can be made visible on TV settings that don't display all pixels. (#1439) [@dougbinks] should be called. (#923, #993)
- Scrolling: Fixed a case where using SetScrollHere(1.0f) at the bottom of a window on the same frame the window height
has been growing would have the scroll clamped using the previous height. (#1804)
- MenuBar: Made BeginMainMenuBar() honor style.DisplaySafeAreaPadding so the text can be made visible on TV settings that
don't display all pixels. (#1439) [@dougbinks]
- InputText: On Mac OS X, filter out characters when the CMD modifier is held. (#1747) [@sivu] - InputText: On Mac OS X, filter out characters when the CMD modifier is held. (#1747) [@sivu]
- InputText: On Mac OS X, support CMD+SHIFT+Z for Redo. CMD+Y is also supported as major apps seems to default to support both. (#1765) [@lfnoise] - InputText: On Mac OS X, support CMD+SHIFT+Z for Redo. CMD+Y is also supported as major apps seems to default to support both. (#1765) [@lfnoise]
- InputText: Fixed returning true when edition is cancelled with ESC and the current buffer matches the initial value. - InputText: Fixed returning true when edition is cancelled with ESC and the current buffer matches the initial value.
- InputFloat,InputFloat2,InputFloat3,InputFloat4: Added variations taking a more flexible and consistent optional "const char* format" parameter instead of "int decimal_precision". - InputFloat,InputFloat2,InputFloat3,InputFloat4: Added variations taking a more flexible and consistent optional
This allow using custom formats to display values in scientific notation, and is generally more consistent with other API. Obsoleted functions using the optional "int decimal_precision" parameter. (#648) "const char* format" parameter instead of "int decimal_precision". This allow using custom formats to display values
- DragFloat, DragInt: Cancel mouse tweak when current value is initially past the min/max boundaries and mouse is pushing in the same direction (keyboard/gamepad version already did this). in scientific notation, and is generally more consistent with other API.
Obsoleted functions using the optional "int decimal_precision" parameter. (#648, #712)
- DragFloat, DragInt: Cancel mouse tweak when current value is initially past the min/max boundaries and mouse is pushing
in the same direction (keyboard/gamepad version already did this).
- DragFloat, DragInt: Honor natural type limits (e.g. INT_MAX, FLT_MAX) instead of wrapping around. (#708, #320) - DragFloat, DragInt: Honor natural type limits (e.g. INT_MAX, FLT_MAX) instead of wrapping around. (#708, #320)
- DragFloat, SliderFloat: Fixes to allow input of scientific notation numbers when using CTRL+Click to input the value. (~#648, #1011) - DragFloat, SliderFloat: Fixes to allow input of scientific notation numbers when using CTRL+Click to input the value. (~#648, #1011)
- DragFloat, SliderFloat: Rounding-on-write uses the provided format string instead of parsing the precision from the string, which allows for finer uses of %e %g etc. (#648, #642) - DragFloat, SliderFloat: Rounding-on-write uses the provided format string instead of parsing the precision from the string,
- DragFloat: Improved computation when using the power curve. Improved lost of input precision with very small steps. Added an assert than power-curve requires a min/max range. (~#642) which allows for finer uses of %e %g etc. (#648, #642)
- DragFloat: Improved computation when using the power curve. Improved lost of input precision with very small steps.
Added an assert than power-curve requires a min/max range. (~#642)
- DragFloat: The 'power' parameter is only honored if the min/max parameter are also setup. - DragFloat: The 'power' parameter is only honored if the min/max parameter are also setup.
- DragInt, SliderInt: Fixed handling of large integers (we previously passed data around internally as float, which reduced the range of valid integers). - DragInt, SliderInt: Fixed handling of large integers (we previously passed data around internally as float, which reduced
the range of valid integers).
- ColorEdit: Fixed not being able to pass the ImGuiColorEditFlags_NoAlpha or ImGuiColorEditFlags_HDR flags to SetColorEditOptions(). - ColorEdit: Fixed not being able to pass the ImGuiColorEditFlags_NoAlpha or ImGuiColorEditFlags_HDR flags to SetColorEditOptions().
- Nav: Fixed hovering a Selectable() with the mouse so that it update the navigation cursor (as it happened in the pre-1.60 navigation branch). (#787) - Nav: Fixed hovering a Selectable() with the mouse so that it update the navigation cursor (as it happened in the pre-1.60 navigation branch). (#787)
- Style: Changed default style.DisplaySafeAreaPadding values from (4,4) to (3,3) so it is smaller than FramePadding and has no effect on main menu bar on a computer. (#1439) - Style: Changed default style.DisplaySafeAreaPadding values from (4,4) to (3,3) so it is smaller than FramePadding and has no effect on main menu bar on a computer. (#1439)
@ -1141,6 +1488,469 @@ Other Changes:
- Various extra comments and clarification in the code. - Various extra comments and clarification in the code.
- Various other fixes and optimizations. - Various other fixes and optimizations.
-----------------------------------------------------------------------
VERSION 1.47 (2015-12-25)
-----------------------------------------------------------------------
Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.47
Changes:
- Rebranding "ImGui" -> "dear imgui" as an optional first name to reduce ambiguity with IMGUI term. (#21)
- Added ProgressBar(). (#333)
- InputText(): Added ImGuiInputTextFlags_Password mode: hide display, disable logging/copying to clipboard. (#237, #363, #374)
- Added GetColorU32() helper to retrieve color given enum with global alpha and extra applied.
- Added ImGuiIO::ClearInputCharacters() superfluous helper.
- Fixed ImDrawList draw command merging bug where using PopClipRect() along with PushTextureID()/PopTextureID() functions
would occasionally restore an incorrect clipping rectangle.
- Fixed ImDrawList draw command merging so PushTextureID(XXX)/PopTextureID()/PushTextureID(XXX) sequence are now properly merged.
- Fixed large popups positioning issues when their contents on either axis is larger than DisplaySize,
and WindowPadding < DisplaySafeAreaPadding.
- Fixed border rendering in various situations when using non-pixel aligned glyphs.
- Fixed border rendering of windows to always contain the border within the window.
- Fixed Shutdown() leaking font atlas data if NewFrame() was never called. (#396, #303)
- Fixed int>void\* warnings for 64-bits architectures with fancy warnings enabled.
- Renamed the dubious Color() helpers to ValueColor() - dangerously named, rarely used and probably to be made obsolete.
- InputText(): Fixed and better handling of using keyboard while mouse button if being held and dragging. (#429)
- InputText(): Replace OS IME (Input Method Editor) cursor on top-left when we are not text editing.
- TreeNode(), CollapsingHeader(), Bullet(), BulletText(): various sizing and layout fixes to better support laying out
multiple item with different height on same line. (#414, #282)
- Begin(): Initial window creation with ImGuiWindowFlags_NoBringToFrontOnFocus flag pushes it at the front of global window list.
- BeginPopupContextWindow() and BeginPopupContextVoid() reopen window on subsequent click. (#439)
- ColorEdit4(): Fixed broken tooltip on hovering the color button. (actually fixes #373, #380)
- ImageButton(): uses FrameRounding up to a maximum of available framing size. (#394)
- Columns: Fixed bug with indentation within columns, also making code a bit shorter/faster. (#414, #125)
- Columns: Columns set with no implicit id include the columns count within the id to reduce collisions. (#125)
- Columns: Removed one unnecessary allocation when columns are not used by a window. (#125)
- ImFontAtlas: Tweaked GetGlyphRangesJapanese() so it is easier to modify.
- ImFontAtlas: Updated stb_rect_pack.h to 0.08.
- Metrics: Fixed computing ImDrawCmd bounding box when the draw buffer have been unindexed.
- Demo: Added a simple "Property Editor" demo applet. (#125, #414)
- Demo: Fixed assertion in "Custom Rendering" demo when holding both mouse buttons. (#393)
- Demo: Lots of extra comments, fixes.
- Demo: Tweaks to Style Editor.
- Examples: Not clearing input data/tex data in atlas (will be required for dynamic atlas anyway).
- Examples: Added /Zi (output debug information) to Win32 batch files.
- Examples: Various fixes for resizing window and recreating graphic context.
- Examples: OpenGL2/3: Save/restore viewport as part of default render function. (#392, #441).
- Examples; OpenGL3: Fixed gl3w.c for Linux when compiled with a C++ compiler. (#411)
- Examples: DirectX: Removed assumption about Unicode build in example main.cpp. (#399)
- Examples: DirectX10: Added DirectX10 example. (#424)
- Examples: DirectX11: Downgraded requirement from shader model 5.0 to 4.0. (#420)
- Examples: DirectX11: Removed Debug flag from graphics context. (#415)
- Examples: Added SDL+OpenGL3 example. (#356)
-----------------------------------------------------------------------
VERSION 1.46 (2015-10-18)
-----------------------------------------------------------------------
Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.46
Changes:
- Begin*(): added ImGuiWindowFlags_NoFocusOnAppearing flag. (#314)
- Begin*(): added ImGuiWindowFlags_NoBringToFrontOnFocus flag.
- Added GetDrawData() alternative to setting a Render function pointer in ImGuiIO structure.
- Added SetClipboardText(), GetClipboardText() helper shortcuts that user code can call directly without reading
from the ImGuiIO structure (to match MemAlloc/MemFree)
- Fixed handling of malformed UTF-8 at the end of a non-zero terminated string range.
- Fixed mouse click detection when passing DeltaTime 0.0. (#338)
- Fixed IsKeyReleased() and IsMouseReleased() returning true on the first frame.
- Fixed using SetNextWindow\* functions on Modal windows with a ImGuiSetCond_Appearing condition. (#377)
- IsMouseHoveringRect(): Added 'bool clip' parameter to disable clipping provided rectangle. (#316)
- InputText(): added ImGuiInputTextFlags_ReadOnly flag. (#211)
- InputText(): lose cursor/undo-stack when reactivating focus is buffer has changed size.
- InputText(): fixed ignoring text inputs when ALT or ALTGR are pressed. (#334)
- InputText(): fixed mouse-dragging not tracking the cursor when text doesn't fit. (#339)
- InputText(): fixed cursor pixel-perfect alignment when horizontally scrolling.
- InputText(): fixed crash when passing a buf_size==0 (which can be of use for read-only selectable text boxes). (#360)
- InputFloat() fixed explicit precision modifier, both display and input were broken.
- PlotHistogram(): improved rendering of histogram with a lot of values.
- Dummy(): creates an item so functions such as IsItemHovered() can be used.
- BeginChildFrame() helper: added the extra_flags parameter.
- Scrollbar: fixed rounding of background + child window consistenly have ChildWindowBg color under ScrollbarBg fill. (#355).
- Scrollbar: background color less translucent in default style so it works better when changing background color.
- Scrollbar: fixed minor rendering offset when borders are enabled. (#365)
- ImDrawList: fixed 1 leak per ImDrawList using the ChannelsSplit() API (via Columns). (#318)
- ImDrawList: fixed rectangle rendering glitches with width/height <= 1/2 and rounding enabled.
- ImDrawList: AddImage() uv parameters default to (0,0) and (1,1).
- ImFontAtlas: Added TexDesiredWidth and tweaked default cheapo best-width choice. (#327)
- ImFontAtlas: Added GetGlyphRangesKorean() helper to retrieve unicode ranges for Korean. (#348)
- ImGuiTextFilter::Draw() helper return bool and build when filter is modified.
- ImGuiTextBuffer: added c_str() helper.
- ColorEdit4(): fixed hovering the color button always showing 1.0 alpha. (#373)
- ColorConvertFloat4ToU32() round the floats instead of truncating them.
- Window: Fixed window lower-right clipping limit so it plays more friendly with both OpenGL and DirectX coordinates.
- Internal: Extracted a EndFrame() function out of Render() but kept it internal/private + clarified some asserts. (#335)
- Internal: Added missing IMGUI_API definitions in imgui_internal.h (#326)
- Internal: ImLoadFileToMemory() return void\* instead of taking void*\* + allow optional int\* file_size.
- Demo: Horizontal scrollbar demo allows to enable simultanaeous scrollbars on both axises.
- Tools: binary_to_compressed_c.cpp: added -nocompress option.
- Examples: Added example for the Marmalade platform.
- Examples: Added batch files to build Windows examples with VS.
- Examples: OpenGL3: Saving/restoring more GL state correctly. (#347)
- Examples: OpenGL2/3: Added msys2/mingw64 target to Makefiles.
-----------------------------------------------------------------------
VERSION 1.45 (2015-09-01)
-----------------------------------------------------------------------
Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.45
Breaking Changes:
- With the addition of better horizontal scrolling primitives I had to make some consistency fixes.
`GetCursorPos()` `SetCursorPos()` `GetContentRegionMax()` `GetWindowContentRegionMin()` `GetWindowContentRegionMax()`
are now incorporating the scrolling amount. They were incorrectly not incorporating this amount previously.
It PROBABLY shouldn't break anything, but that depends on how you used them. Namely:
- If you always used SetCursorPos() with values relative to GetCursorPos() there shouldn't be a problem.
However if you used absolute coordinates, note that SetCursorPosY(100.0f) will put you at +100 from the initial Y position (which may be scrolled out of the view), NOT at +100 from the window top border. Since there wasn't any official scrolling value on X axis (past just manually moving the cursor) this can only affect you if you used to set absolute coordinates on the Y axis which is hopefully rare/unlikely, and trivial to fix.
- The value of GetWindowContentRegionMax() isn't necessarily close to GetWindowWidth() if horizontally scrolling.
Previously they were roughly interchangeable (roughly because the content region exclude window padding).
Other Changes:
- Added Horizontal Scrollbar via ImGuiWindowFlags_HorizontalScroll (#246).
- Added GetScrollX(), GetScrollX(), GetScrollMaxX() apis (#246).
- Added SetNextWindowContentSize(), SetNextWindowContentWidth() to explicitly set the content size of a window, which
define the range of scrollbar. When set explicitly it also define the base value from which widget width are derived.
- Added IO.WantTextInput telling when ImGui is expecting text input, so that e.g. OS on-screen keyboard can be enabled.
- Added printf attribute to printf-like text formatting functions (Clang/GCC).
- Added GetMousePosOnOpeningCurrentPopup() helper.
- Added GetContentRegionAvailWidth() helper.
- Malformed UTF-8 data don't terminate string, output 0xFFFD instead (#307).
- ImDrawList: Added AddBezierCurve(), PathBezierCurveTo() API for cubic bezier curves (#311).
- ImDrawList: Allow to override ImDrawIdx type (#292).
- ImDrawList: Added an assert on overflowing index value (#292).
- ImDrawList: Fixed issues with channels split/merge. Now functional without manually adding a draw cmd. Added comments.
- ImDrawData: Added ScaleClipRects() helper useful when rendering scaled. (#287).
- Fixed Bullet() inconsistent layout behaviour when clipped.
- Fixed IsWindowHovered() not taking account of window hoverability (may be disabled because of a popup).
- Fixed InvisibleButton() not honoring negative size consistently with other widgets that do so.
- Fixed OpenPopup() accessing current window, effectively opening "Debug" when called from an empty window stack.
- TreeNode(): Fixed IsItemHovered() result being inconsistent with interaction visuals (#282).
- TreeNode(): Fixed mouse interaction padding past the node label being accounted for in layout (#282).
- BeginChild(): Passing a ImGuiWindowFlags_NoMove inhibits moving parent window from this child.
- BeginChild() fixed missing rounding for child sizes which leaked into layout and have items misaligned.
- Begin(): Removed default name = "Debug" parameter. We already have a "Debug" window pushed to the stack in the first place so it's not really a useful default.
- Begin(): Minor fixes with windows main clipping rectangle (e.g. child window with border).
- Begin(): Window flags are only read on the first call of the frame. Subsequent calls ignore flags, which allows appending to a window without worryin about flags.
- InputText(): ignore character input when ctrl/alt are held. (Normally those text input are ignored by most wrappers.) (#279).
- Demo: Fixed incorrectly formed string passed to Combo (#298).
- Demo: Added simple Log demo.
- Demo: Added horizontal scrolling example + enabled in console, log and child examples (#246).
- Style: made scrollbars rounded by default. Because nice. Minor menu bar background alpha tweak. (#246)
- Metrics: display indices along with triangles count (#299) and some internal state.
- ImGuiTextFilter::PassFilter() supports string range. Added [] helper to ImGuiTextBuffer.
- ImGuiTextFilter::Draw() default parameter width=0.0f for no override, allow override with negative values.
- Examples: OpenGL2/OpenGL3: fix for retina displays. Default font current lack crispness.
- Examples: OpenGL2/OpenGL3: save/restore more GL state correctly.
- Examples: DirectX9/DirectX11: resizing buffers dynamically (#299).
- Examples: DirectX9/DirectX11: added missing middle mouse button to Windows event handler.
- Examples: DirectX11: fix for Visual Studio 2015 presumably shipping with an updated version of DX11.
- Examples: iOS: fixed missing files in project.
-----------------------------------------------------------------------
VERSION 1.44 (2015-08-08)
-----------------------------------------------------------------------
Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.44
Breaking Changes:
- imgui.cpp has been split intro extra files: imgui_demo.cpp, imgui_draw.cpp, imgui_internal.h.
Add the two extra .cpp to your project or #include them from another .cpp file. (#219)
Other Changes:
- Internal data structure and several useful functions are now exposed in imgui_internal.h. This should make it easier
and more natural to extend ImGui. However please note that none of the content in imgui_internal.h is guaranteed
for forward-compatibility and code using those types/functions may occasionally break. (#219)
- All sample code is in imgui_demo.cpp. Please keep this file in your project and consider allowing your code to call
the ShowTestWindow() function as de-facto guide to ImGui features. It will be stripped out by the linker when unused.
- Added GetContentRegionAvail() helper (basically GetContentRegionMax() - GetCursorPos()).
- Added ImGuiWindowFlags_NoInputs for totally input-passthru window.
- Button(): honor negative size consistently with other widgets that do so (width -100 to align the button 100 pixels
before the right-most position of the contents region).
- InputTextMultiline(): honor negative size consistently with other widgets that do so.
- Combo() clamp popup to lower edge of visible area.
- InputInt(): value doesn't pass through an int>float>int casting chain, fix handling lost of precision with "large" integer.
- InputInt() allow hexadecimal input (awkwardly via ImGuiInputTextFlags_CharsHexadecimal but we will allow format
string in InputInt* later).
- Checkbox(), RadioButton(): fixed scaling of checkbox and radio button for the filling of "active" visual.
- Columns: never assume horizontal space for scrollbar if NoScrollbar flag is explicitly set.
- Slider: fixed using FramePadding between frame and grab visual. Scaling that spacing would look odd.
- Fixed lower-right resize grip hit box not scaling along with its rendered size (#287)
- ImDrawList: Fixed angles in ImDrawList::PathArcTo(), PathArcToFast() (v1.43) being off by an extra PI for no reason.
- ImDrawList: Added ImDrawList::AddText() shorthand helper.
- ImDrawList: Add missing support for anti-aliased thick-lines (#133, also ref #288)
- ImFontAtlas: Added AddFontFromMemoryCompressedBase85TTF() to load base85 encoded font string. Default font encoded
as base85 saves ~100 lines / 26 KB of source code. Added base85 output to the binary_to_compressed_c tool.
- Build fix for MinGW (#276).
- Examples: OpenGL3: Fixed running on script core profiles for OSX (#277).
- Examples: OpenGL3: Simplified code using glBufferData for vertices as well (#277, #278)
- Examples: DirectX11: Clear font texture view to ensure Release() doesn't get called twice (#290).
- Updated to stb_truetype 1.07 (back to vanilla version as our minor changes are now in master & fix unlikely assert
with odd fonts (#280)
-----------------------------------------------------------------------
VERSION 1.43 (2015-07-17)
-----------------------------------------------------------------------
Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.43
Breaking Changes:
- This is a rather important release and we unfortunately had to break the rendering API.
ImGui now requires you to render indexed vertices instead of non-indexed ones. The fix should be very easy.
Sorry for that! This change is saving a fair amount of CPU/GPU and enables us to get anti-aliasing for a marginal cost.
Each ImDrawList now contains both a vertex buffer and an index buffer. For each command, render ElemCount/3 triangles
using indices from the index buffer.
- If you are using a vanilla copy of one of the imgui_impl_XXXX.cpp provided in the example, you just need to update
your copy and you can ignore the rest.
- The signature of the io.RenderDrawListsFn handler has changed
From: ImGui_XXXX_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count)
To: ImGui_XXXX_RenderDrawLists(ImDrawData* draw_data)
With: argument 'cmd_lists' -> 'draw_data->CmdLists'
argument 'cmd_lists_count' -> 'draw_data->CmdListsCount'
ImDrawList 'commands' -> 'CmdBuffer'
ImDrawList 'vtx_buffer' -> 'VtxBuffer'
ImDrawList n/a -> 'IdxBuffer' (new)
ImDrawCmd 'vtx_count' -> 'ElemCount'
ImDrawCmd 'clip_rect' -> 'ClipRect'
ImDrawCmd 'user_callback' -> 'UserCallback'
ImDrawCmd 'texture_id' -> 'TextureId'
- If you REALLY cannot render indexed primitives, you can call the draw_data->DeIndexAllBuffers() method to de-index
the buffers. This is slow and a waste of CPU/GPU. Prefer using indexed rendering!
Refer to code in the examples/ folder or ask on the GitHub if you are unsure of how to upgrade. Please upgrade!
Other Changes:
- Added anti-aliasing on lines and shapes based on primitives by @MikkoMononen (#133).
Between the use of indexed-rendering and the fact that the entire rendering codebase has been optimized and massaged
enough, with anti-aliasing enabled ImGui 1.43 is now running FASTER than 1.41.
Made some extra effort in making the code run faster in your typical Debug build.
- Anti-aliasing can be disabled in the ImGuiStyle structure via the AntiAliasedLines/AntiAliasedShapes fields for further gains.
- ImDrawList: Added AddPolyline(), AddConvexPolyFilled() with optional anti-aliasing.
- ImDrawList: Added stateful path building and stroking API. PathLineTo(), PathArcTo(), PathRect(), PathFill(), PathStroke()
with optional anti-aliasing.
- ImDrawList: Added AddRectFilledMultiColor() helper.
- ImDrawList: Added multi-channel rendering so out of order elements can be rendered in separate channels and then merged
back together (used by columns).
- ImDrawList: Fixed merging draw commands when equal clip rectangles are in the two first commands.
- ImDrawList: Fixed window draw lists not destructed properly on Shutdown().
- ImDrawData: Added DeIndexAllBuffers() helper.
- Added lots of new font options ImFontAtlas::AddFont() and the new ImFontConfig structure.
- Added support for oversampling (ImFontConfig: OversampleH, OversampleV) and sub-pixel positioning (ImFontConfig: PixelSnapH).
Oversampling allows sub-pixel positioning but can also be used as a way to get some leeway with scaling fonts without re-rasterizing.
- Added GlyphExtraSpacing option to add extra horizontal spacing between characters (#242).
- Added MergeMode option to merge glyphs from different font inputs into a same font (#182, #232).
- Added FontDataOwnedByAtlas option to keep ownership from the TTF data buffer and request the atlas to make a copy (#220).
- Updated to stb_truetype 1.06 (+ minor mods) with better font rasterization.
- InputText: Added ImGuiInputTextFlags_NoHorizontalScroll flag.
- InputText: Added ImGuiInputTextFlags_AlwaysInsertMode flag.
- InputText: Added HasSelection() helper in ImGuiTextEditCallbackData as a clarification.
- InputText: Fix for using END key on a multi-line text editor (#275)
- Columns: Dispatch render of each column in a sub-draw list and merge on closure, saving a lot of draw calls! (#125)
- Popups: Fixed Combo boxes inside menus. (#272)
- Style: Added GrabRounding setting to make the sliders etc. grabs rounded.
- Changed SameLine() parameters from int to float.
- Fixed incorrect assert triggering when code stole ActiveID from user moving a window by calling e.g. SetKeyboardFocusHere().
- Fixed CollapsingHeader() label rendering outside its frame in columns context where ClipRect max isn't aligned with the
right-side of the header.
- Metrics window: calculate bounding box of actual vertices when hovering a draw list.
- Examples: Showing more information in the Fonts section.
- Examples: Added a gratuitous About window.
- Examples: Updated all examples code (OpenGL/DX9/DX11/SDL/Allegro/iOS) to use indexed rendering.
- Examples: Fixed the SDL2 example to support Unicode text input (#274).
-----------------------------------------------------------------------
VERSION 1.42 (2015-07-08)
-----------------------------------------------------------------------
Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.42
Breaking Changes:
- Renamed SetScrollPosHere() to SetScrollHere(). Kept inline redirection function (will obsolete).
- Renamed GetScrollPosY() to GetScrollY(). Necessary to reduce confusion and make scrolling API consistent,
because positions (e.g. cursor position) are not equivalent to scrolling amount.
- Removed obsolete GetDefaultFontData() function that would assert anyway.
If you are updating from <1.30 you'll get a compile error instead of an assertion. (obsoleted 2015/01/11)
Other Changes:
- Added SDL2 example application (courtesy of @CedricGuillemet)
- Added iOS example application (courtesy of @joeld42)
- Added Allegro 5 example application (courtesy of @bggd)
- Added TitleBgActive color in style so focused window is made visible. (#253)
- Added CaptureKeyboardFromApp() / CaptureMouseFromApp() to manually enforce inputs capturing.
- Added DragFloatRange2() DragIntRange2() helpers. (#76)
- Added a Y centering ratio to SetScrollFromCursorPos() which can be used to aim the top or bottom of the window. (#150)
- Added SetScrollY(), SetScrollFromPos(), GetCursorStartPos() for manual scrolling manipulations. (#150).
- Added GetKeyIndex() helper for converting from ImGuiKey_\* enum to user's keycodes. Basically pulls from io.KeysMap[].
- Added missing ImGuiKey_PageUp, ImGuiKey_PageDown so more UI code can be written without referring to implementation-side keycodes.
- MenuItem() can be activated on release. (#245)
- Allowing NewFrame() with DeltaTime==0.0f to not assert.
- Fixed IsMouseDragging(). (#260)
- Fixed PlotLines(), PlotHistogram() using incorrect hovering test so they would show their tooltip even when there is
a popup between mouse and the graph.
- Fixed window padding being reported incorrectly for child windows with borders when parent have no borders.
- Fixed a bug with TextUnformatted() clipping of long text blob when clipping y1 line sits on the first line of text. (#257)
- Fixed text baseline alignment of small button (no padding) after regular buttons.
- Fixed ListBoxHeader() not honoring negative sizes the same way as BeginChild() or BeginChildFrame(). (#263)
- Fixed warnings for more pedantic compiler settings (#258).
- ImVector<> cannot be re-defined anymore, cannot be replaced with std::vector<>. Allowed us to clean up and optimize
lots of code. Yeah! (#262)
- ImDrawList: store pointer to their owner name for easier auditing/debugging.
- Examples: added scroll tracking example with SetScrollFromCursorPos().
- Examples: metrics windows render clip rectangle when hovering over a draw call.
- Lots of small optimization (particularly to run faster on unoptimized builds) and tidying up.
- Added font links in extra_fonts/ + instructions for using compressed fonts in C array.
-----------------------------------------------------------------------
VERSION 1.41 (2015-06-26)
-----------------------------------------------------------------------
Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.41
Breaking Changes:
- Changed ImageButton() default bg_col parameter from (0,0,0,1) (black) to (0,0,0,0) (transparent).
Only makes a difference when texture have transparency.
- Changed Selectable() API from (label, selected, size) to (label, selected, flags, size).
Size override should be used very rarely so hopefully it doesn't affect many people. Sorry!
Other Changes:
- Added InputTextMultiline() multi-line text editor, vertical scrolling, selection, optimized enough to handle rather
big chunks of text in stateless context (thousands of lines are ok), option for allowing Tab to be input, option
for validating with Return or Ctrl+Return (#200).
- Added modal window API, BeginPopupModal(), follows the popup api scheme. Modal windows can be closed by clicking
outside. By default the rest of the screen is dimmed (using ImGuiCol_ModalWindowDarkening). Modal windows can be stacked.
- Added GetGlyphRangesCyrillic() helper (#237).
- Added SetNextWindowPosCenter() to center a window prior to knowing its size. (#249)
- Added IsWindowHovered() helper.
- Added IsMouseReleased(), IsKeyReleased() helpers to allow to user to avoid tracking them. (#248)
- Allow Set*WindowSize() calls to be used with popups.
- Window: AutoFit can be triggered on each axis separately via SetNextWindowSize(), etc.
- Window: fixed scrolling with mouse wheel while window was collapsed.
- Window: fixed mouse wheel scroll issues.
- DragFloat(), SliderFloat(): Fixed rounding of negative numbers which sometime made the negative lower bound unreachable.
- InputText(): lifted character count limit.
- InputText(): fixes in case of using per-window font scaling.
- Selectable(), MenuItem(): do not use frame rounding for hovering/selection.
- Selectable(): Added flag ImGuiSelectableFlags_DontClosePopups.
- Selectable(): Added flag ImGuiSelectableFlags_SpanAllColumns (#125).
- Combo(): Fixed issue with activating a Combo() not taking active id (#241).
- ColorButton(), ColorEdit4(): fix to ensure that the colored square stays square when non-default padding settings are used.
- BeginChildFrame(): returns bool like BeginChild() for clipping.
- SetScrollPosHere(): takes account of item height + more accurate centering + fixed precision issue.
- ImFont: ignoring '\r'.
- ImFont: added GetCharAdvance() helper. Exposed font Ascent and font Descent.
- ImFont: additional rendering optimizations.
- Metrics windows display storage size.
-----------------------------------------------------------------------
VERSION 1.40 (2015-05-31)
-----------------------------------------------------------------------
Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.40
Breaking Changes:
- The BeginPopup() API (introduced in 1.37) had to be changed to allow for stacked popups and menus.
Use OpenPopup() to toggle the opened state and BeginPopup() to append.**
- The third parameter of Button(), 'repeat_if_held' has been removed. While it's been very rarely used,
some code will possibly break if you didn't rely on the default parameter.
Use PushButtonRepeat()/PopButtonRepeat() to configure repeat.
- Renamed IsRectClipped() to !IsRectVisible() for consistency (opposite return value!). Kept inline redirection function (will obsolete)
- Renamed GetWindowCollapsed() to IsWindowCollapsed() for consistency. Kept inline indirection function (will obsolete).
Other Changes:
- Menus: Added a menu system! Menus are typically populated with menu items and sub-menus, but you can add any sort of
widgets in them (buttons, text inputs, sliders, etc.). (#126)
- Menus: Added MenuItem() to append a menu item. Optional shortcut display, acts a button & toggle with checked/unchecked state,
disabled mode. Menu items can be used in any window.
- Menus: Added BeginMenu() to append a sub-menu. Note that you generally want to add sub-menu inside a popup or a menu-bar.
They will work inside a normal window but it will be a bit unusual.
- Menus: Added BeginMenuBar() to append to window menu-bar (set ImGuiWindowFlags_MenuBar to enable).
- Menus: Added BeginMainMenuBar() helper to append to a fullscreen main menu-bar.
- Popups: Support for stacked popups. Each popup level inhibit inputs to lower levels. The menus system is based on this. (#126).
- Popups: Added BeginPopupContextItem(), BeginPopupContextWindow(), BeginPopupContextVoid() to create a popup window on mouse-click.
- Popups: Popups have borders by default (#197), attenuated border alpha in default theme.
- Popups & Tooltip: Fit within display. Handling various positioning/sizing/scrolling edge cases. Better hysteresis when moving
in corners. Tooltip always tries to stay away from mouse-cursor.
- Added ImGuiStorage::GetVoidPtrRef() for manipulating stored void*.
- Added IsKeyDown() IsMouseDown() as convenience and for consistency with existing functions (instead of reading them from IO structures).
- Added Dummy() helper to advance layout by a given size. Unlike InvisibleButton() this doesn't catch any click.
- Added configurable io.KeyRepeatDelay, io.KeyRepeatRate keyboard and mouse repeat rate.
- Added PushButtonRepeat() / PopButtonRepeat() to enable hold-button-to-repeat press on any button.
- Removed the third 'repeat' parameter of Button().
- Added IsAnyItemHovered() helper.
- Added GetItemsLineHeightWithSpacing() helper.
- Added ImGuiListClipper helper for clipping large list of evenly sized items, to avoid using CalcListClipping() directly.
- Separator: within group start on group horizontal offset. (#205)
- InputText: Fixed incorrect edit state after text buffer is appended to by user via the callback. (#206)
- InputText: CTRL+letter-key shortcuts (e.g. CTRL+C/V/X) makes sure only CTRL is pressed. (#214)
- InputText: Fixed cursor generating a zero-width wire-frame rectangle turning into a division by zero (would go unnoticed
unless you trapped exceptions).
- InputFloatN/InputIntN: Flags parameter added to match scalar versions. (#218)
- Selectable: Horizontal filling not declared to ItemSize() so Selectable(),SameLine() works and we can better auto-fit the window.
- Selectable: Handling text baseline alignment for line that aren't of text height.
- Combo: Empty label doesn't add ItemInnerSpacing alignment, matching other widgets.
- EndGroup: Carries the text base offset from the last line of the group (sort of incorrect but better than nothing,
should use the first line of the group, will implement in the future).
- Columns: distinguish columns-set ID from other widgets as a convenience, added asserts and sailors.
- ListBox: ListBox() function only use public API to encourage creating custom versions. ListBoxHeader() can return false.
- ListBox: Uses ImGuiListClipper and assume items of matching height, so large lists can be handled.
- Plot: overlay label clipped within frame when not fitting.
- Window: Added ImGuiSetCond_Appearing to test the hidden->visible transition in SetWindow***/SetNextWindow*** functions.
- Window: Auto-fitting cancel out one worth of vertical spacing for vertical symmetry (like what group and tooltip do).
- Window: Default item width for auto-resizing windows expressed as a factor of font height, scales better with different font.
- Window: Fixed auto-fit calculation mismatch of whether a scrollbar will be added by maximum height clamping. Also honor NoScrollBar in the case of height clamping, not adding extra horizontal space.
- Window: Hovering require to hover same child window. Reverted 860cf57 (December 3). Might break something if you have
child overlapping items in parent window.
- Window: Fixed appending multiple times to an existing child via multiple BeginChild/EndChild calls to same child name.
Allows a simple form of out-of-order appending.
- Window: Fixed auto-filling child window using WindowMinSize at their minimum size, irrelevant.
- Metrics: Added io.MetricsActiveWindows counter. (#213.
- Metrics: Added io.MetricsAllocs counter (number of active memory allocations).
- Metrics: ShowMetricsWindow() shows popups stack, allocations.
- Style: Added style.DisplayWindowPadding to prevent windows from reaching edges of display (similar to style.DisplaySafeAreaPadding which is still in effect and also affect popups/tooltips).
- Style: Removed style.AutoFitPadding, using style.WindowPadding makes more sense (the default values were already the same).
- Style: Added style.ScrollbarRounding. (#212)
- Style: Added ImGuiCol_TextDisabled for disabled text. Added TextDisabled() helper.
- Style: Added style.WindowTitleAlign alignment options, to e.g. center title on windows. (#222)
- ImVector: tweak growth strategy, matches vector from VS2010.
- ImFontAtlas: Added ClearFonts(), making the different clear funcs more explicit. (#224)
- ImFontAtlas: Fixed appending new fonts without clearing existing fonts. Clearing input data left to application. (#224)
- ImDrawList: Merge draw command better, cases of multiple Begin/End gets merged properly.
- Store common stacked settings contiguously in memory to avoid heap allocation for unused features, and reduce cache misses.
- Shutdown() tests for g.IO.Fonts not being NULL to ease use of multiple ImGui contexts. (#207)
- Added IMGUI_DISABLE_OBSOLETE_FUNCTIONS define to disable the functions that are meant to be removed.
- Examples: Added ? marks with tooltips next to various widgets. Added more comments in the demo window.
- Examples: Added Menu-bar example.
- Examples: Added Simple Layout example.
- Examples: AutoResize demo doesn't use TextWrapped().
- Examples: Console example uses standard malloc/free, makes more sense as a copy & pastable example.
- Examples: DirectX9/11: Fixed key mapping for down arrow.
- Examples: DirectX9/11: hide OS cursor if ImGui is drawing it. (#155)
- Examples: DirectX11: explicitly set rasterizer state.
- Examples: OpenGL3: Add conditional compilation of forward compat as required by glfw on OSX. (#229)
- Fixed build with Visual Studio 2008 (possibly earlier versions as well).
- Other fixes, comments, tweaks.
----------------------------------------------------------------------- -----------------------------------------------------------------------
For older version, see https://github.com/ocornut/imgui/releases For older version, see https://github.com/ocornut/imgui/releases

View File

@ -9,7 +9,7 @@ Individuals/hobbyists: support continued maintenance and development via the mon
<br>&nbsp;&nbsp;[![Patreon](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/patreon_01.png)](http://www.patreon.com/imgui) <br>&nbsp;&nbsp;[![Patreon](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/patreon_01.png)](http://www.patreon.com/imgui)
Individuals/hobbyists: support continued maintenance and development via PayPal: Individuals/hobbyists: support continued maintenance and development via PayPal:
<br>&nbsp;&nbsp;[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U) <br>&nbsp;&nbsp;[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WGHNC6MBFLZ2S)
Businesses: support continued maintenance and development via support contracts or sponsoring: Businesses: support continued maintenance and development via support contracts or sponsoring:
<br>&nbsp;&nbsp;_E-mail: omarcornut at gmail dot com_ <br>&nbsp;&nbsp;_E-mail: omarcornut at gmail dot com_
@ -20,7 +20,7 @@ Dear ImGui is designed to enable fast iterations and to empower programmers to c
Dear ImGui is particularly suited to integration in games engine (for tooling), real-time 3D applications, fullscreen applications, embedded applications, or any applications on consoles platforms where operating system features are non-standard. Dear ImGui is particularly suited to integration in games engine (for tooling), real-time 3D applications, fullscreen applications, embedded applications, or any applications on consoles platforms where operating system features are non-standard.
See [Software using dear imgui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui), [Quotes](https://github.com/ocornut/imgui/wiki/Quotes) and [Gallery](https://github.com/ocornut/imgui/issues/2265) pages to get an idea of its use cases. See [Software using dear imgui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui), [Quotes](https://github.com/ocornut/imgui/wiki/Quotes) and [Gallery](https://github.com/ocornut/imgui/issues/2529) pages to get an idea of its use cases.
Dear ImGui is self-contained within a few files that you can easily copy and compile into your application/engine: Dear ImGui is self-contained within a few files that you can easily copy and compile into your application/engine:
- imgui.cpp - imgui.cpp
@ -102,7 +102,7 @@ Demo Binaries
------------- -------------
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 some Dear ImGui features, 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 some Dear ImGui features, you can download Windows binaries of the demo app here:
- [imgui-demo-binaries-20181008.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20181008.zip) (Windows binaries, Dear ImGui 1.66 WIP built 2018/10/08, master branch, 5 executables) - [imgui-demo-binaries-20190219.zip](http://www.dearimgui.org/binaries/imgui-demo-binaries-20190219.zip) (Windows binaries, Dear ImGui 1.68 built 2019/02/19, master branch, 5 executables)
The demo applications are unfortunately not yet DPI aware so expect some blurriness on a 4K screen. For DPI awareness in your application, you can load/reload your font at different scale, and scale your Style with `style.ScaleAllSizes()`. The demo applications are unfortunately not yet DPI aware so expect some blurriness on a 4K screen. For DPI awareness in your application, you can load/reload your font at different scale, and scale your Style with `style.ScaleAllSizes()`.
@ -122,20 +122,20 @@ Languages: (third-party bindings)
- Haxe/hxcpp: [linc_imgui](https://github.com/Aidan63/linc_imgui) - Haxe/hxcpp: [linc_imgui](https://github.com/Aidan63/linc_imgui)
- Java: [jimgui](https://github.com/ice1000/jimgui) - Java: [jimgui](https://github.com/ice1000/jimgui)
- JavaScript: [imgui-js](https://github.com/flyover/imgui-js) - JavaScript: [imgui-js](https://github.com/flyover/imgui-js)
- Julia: [CImGui.jl](https://github.com/Gnimuc/CImGui.jl)
- Lua: [LuaJIT-ImGui](https://github.com/sonoro1234/LuaJIT-ImGui), [imgui_lua_bindings](https://github.com/patrickriordan/imgui_lua_bindings) or [lua-ffi-bindings](https://github.com/thenumbernine/lua-ffi-bindings) - Lua: [LuaJIT-ImGui](https://github.com/sonoro1234/LuaJIT-ImGui), [imgui_lua_bindings](https://github.com/patrickriordan/imgui_lua_bindings) or [lua-ffi-bindings](https://github.com/thenumbernine/lua-ffi-bindings)
- Odin: [odin-dear_imgui](https://github.com/ThisDrunkDane/odin-dear_imgui) - Odin: [odin-dear_imgui](https://github.com/ThisDrunkDane/odin-dear_imgui)
- Pascal: [imgui-pas](https://github.com/dpethes/imgui-pas) - Pascal: [imgui-pas](https://github.com/dpethes/imgui-pas)
- PureBasic: [pb-cimgui](https://github.com/hippyau/pb-cimgui) - PureBasic: [pb-cimgui](https://github.com/hippyau/pb-cimgui)
- Python [CyImGui](https://github.com/chromy/cyimgui) or [pyimgui](https://github.com/swistakm/pyimgui) - Python: [pyimgui](https://github.com/swistakm/pyimgui) or [bimpy](https://github.com/podgorskiy/bimpy)
- Ruby: [ruby-imgui](https://github.com/vaiorabbit/ruby-imgui) - Ruby: [ruby-imgui](https://github.com/vaiorabbit/ruby-imgui)
- Rust: [imgui-rs](https://github.com/Gekkio/imgui-rs) or [imgui-rust](https://github.com/nsf/imgui-rust) - Rust: [imgui-rs](https://github.com/Gekkio/imgui-rs) or [imgui-rust](https://github.com/nsf/imgui-rust)
- Swift [swift-imgui](https://github.com/mnmly/Swift-imgui) - Swift [swift-imgui](https://github.com/mnmly/Swift-imgui)
Frameworks: Frameworks:
- Renderers: DirectX 9/10/11/12, Metal, OpenGL2, OpenGL3+/ES2/ES3, Vulkan: [examples/](https://github.com/ocornut/imgui/tree/master/examples) - Renderers: DirectX 9/10/11/12, Metal, OpenGL2, OpenGL3+/ES2/ES3, Vulkan: [examples/](https://github.com/ocornut/imgui/tree/master/examples)
- Platform: GLFW, SDL, Win32, OSX, Freeglut: [examples/](https://github.com/ocornut/imgui/tree/master/examples) - Platform: GLFW, SDL, Win32, OSX, GLUT: [examples/](https://github.com/ocornut/imgui/tree/master/examples)
- Framework: Allegro 5, Marmalade: [examples/](https://github.com/ocornut/imgui/tree/master/examples) - Framework: Allegro 5, Emscripten, Marmalade: [examples/](https://github.com/ocornut/imgui/tree/master/examples)
- Unmerged PR: SDL2 + OpenGLES + Emscripten: [#336](https://github.com/ocornut/imgui/pull/336)
- Unmerged PR: Android: [#421](https://github.com/ocornut/imgui/pull/421) - Unmerged PR: Android: [#421](https://github.com/ocornut/imgui/pull/421)
- Cinder: [Cinder-ImGui](https://github.com/simongeilfus/Cinder-ImGui) - Cinder: [Cinder-ImGui](https://github.com/simongeilfus/Cinder-ImGui)
- Cocos2d-x: [imguix](https://github.com/c0i/imguix), [#551](https://github.com/ocornut/imgui/issues/551) - Cocos2d-x: [imguix](https://github.com/c0i/imguix), [#551](https://github.com/ocornut/imgui/issues/551)
@ -145,12 +145,13 @@ Frameworks:
- Ogre: [ogreimgui](https://bitbucket.org/LMCrashy/ogreimgui/src) - Ogre: [ogreimgui](https://bitbucket.org/LMCrashy/ogreimgui/src)
- OpenFrameworks: [ofxImGui](https://github.com/jvcleave/ofxImGui) - OpenFrameworks: [ofxImGui](https://github.com/jvcleave/ofxImGui)
- OpenSceneGraph/OSG: [gist](https://gist.github.com/fulezi/d2442ca7626bf270226014501357042c) - OpenSceneGraph/OSG: [gist](https://gist.github.com/fulezi/d2442ca7626bf270226014501357042c)
- ORX: [pr #1843](https://github.com/ocornut/imgui/pull/1843) - ORX: [ImGuiOrx](https://github.com/thegwydd/ImGuiOrx), [#1843](https://github.com/ocornut/imgui/pull/1843)
- px_render: [px_render_imgui.h](https://github.com/pplux/px/blob/master/px_render_imgui.h), [#1935](https://github.com/ocornut/imgui/pull/1935)
- LÖVE+Lua: [love-imgui](https://github.com/slages/love-imgui) - LÖVE+Lua: [love-imgui](https://github.com/slages/love-imgui)
- Magnum: [ImGuiIntegration](https://doc.magnum.graphics/magnum/namespaceMagnum_1_1ImGuiIntegration.html) ([example](https://doc.magnum.graphics/magnum/examples-imgui.html)) - Magnum: [ImGuiIntegration](https://doc.magnum.graphics/magnum/namespaceMagnum_1_1ImGuiIntegration.html) ([example](https://doc.magnum.graphics/magnum/examples-imgui.html))
- NanoRT: [syoyo/imgui](https://github.com/syoyo/imgui/tree/nanort) - NanoRT: [syoyo/imgui](https://github.com/syoyo/imgui/tree/nanort)
- Qt3d: [imgui-qt3d](https://github.com/alpqr/imgui-qt3d), QOpenGLWindow [qtimgui](https://github.com/ocornut/imgui/issues/1910) - Qt: [imgui-qt3d](https://github.com/alpqr/imgui-qt3d) / [QOpenGLWindow (qtimgui)](https://github.com/ocornut/imgui/issues/1910) / [QtDirect3D](https://github.com/giladreich/QtDirect3D) / [qt6](https://github.com/alpqr/qvk6/tree/imgui/examples/rhi/imguidemo)
- SFML: [imgui-sfml](https://github.com/EliasD/imgui-sfml) - SFML: [imgui-sfml](https://github.com/eliasdaler/imgui-sfml)
- Software renderer: [imgui_software_renderer](https://github.com/emilk/imgui_software_renderer) - Software renderer: [imgui_software_renderer](https://github.com/emilk/imgui_software_renderer)
- Unreal Engine 4: [segross/UnrealImGui](https://github.com/segross/UnrealImGui) or [sronsse/UnrealEngine_ImGui](https://github.com/sronsse/UnrealEngine_ImGui) - Unreal Engine 4: [segross/UnrealImGui](https://github.com/segross/UnrealImGui) or [sronsse/UnrealEngine_ImGui](https://github.com/sronsse/UnrealEngine_ImGui)
@ -159,8 +160,8 @@ For other bindings: see [Bindings](https://github.com/ocornut/imgui/wiki/Binding
Roadmap Roadmap
------- -------
Some of the goals for 2019 are: Some of the goals for 2019 are:
- Finish work on docking, tabs. (see [#2109](https://github.com/ocornut/imgui/issues/2109), public branch looking for feedback) - Finish work on docking, tabs. (see [#2109](https://github.com/ocornut/imgui/issues/2109), in public `docking` branch looking for feedback)
- Finish work on multiple viewports / multiple OS windows. (see [#1542](https://github.com/ocornut/imgui/issues/1542), public branch looking for feedback) - Finish work on multiple viewports / multiple OS windows. (see [#1542](https://github.com/ocornut/imgui/issues/1542), in public `docking` branch looking for feedback)
- Finish work on gamepad/keyboard controls. (see [#787](https://github.com/ocornut/imgui/issues/787)) - Finish work on gamepad/keyboard controls. (see [#787](https://github.com/ocornut/imgui/issues/787))
- Add an automation and testing system, both to test the library and end-user apps. (see [#435](https://github.com/ocornut/imgui/issues/435)) - Add an automation and testing system, both to test the library and end-user apps. (see [#435](https://github.com/ocornut/imgui/issues/435))
- Make Columns better. (they are currently pretty terrible!) - Make Columns better. (they are currently pretty terrible!)
@ -175,9 +176,9 @@ User screenshots:
<br>[Gallery Part 4](https://github.com/ocornut/imgui/issues/973) (Jan 2017 to Aug 2017) <br>[Gallery Part 4](https://github.com/ocornut/imgui/issues/973) (Jan 2017 to Aug 2017)
<br>[Gallery Part 5](https://github.com/ocornut/imgui/issues/1269) (Aug 2017 to Feb 2018) <br>[Gallery Part 5](https://github.com/ocornut/imgui/issues/1269) (Aug 2017 to Feb 2018)
<br>[Gallery Part 6](https://github.com/ocornut/imgui/issues/1607) (Feb 2018 to June 2018) <br>[Gallery Part 6](https://github.com/ocornut/imgui/issues/1607) (Feb 2018 to June 2018)
<br>[Gallery Part 7](https://github.com/ocornut/imgui/issues/1902) (June 2018 to January 2018) <br>[Gallery Part 7](https://github.com/ocornut/imgui/issues/1902) (June 2018 to January 2019)
<br>[Gallery Part 8](https://github.com/ocornut/imgui/issues/2265) (January 2018 onward) <br>[Gallery Part 8](https://github.com/ocornut/imgui/issues/2265) (January 2019 to May 2019)
<br>Also see the [Mega screenshots](https://github.com/ocornut/imgui/issues/1273) for an idea of the available features. <br>[Gallery Part 9](https://github.com/ocornut/imgui/issues/2529) (May 2019 onward)
Custom engine Custom engine
[![screenshot game](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v149/gallery_TheDragonsTrap-01-thumb.jpg)](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png) [![screenshot game](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v149/gallery_TheDragonsTrap-01-thumb.jpg)](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
@ -197,61 +198,66 @@ References
The Immediate Mode GUI paradigm may at first appear unusual to some users. This is mainly because "Retained Mode" GUIs have been so widespread and predominant. The following links can give you a better understanding about how Immediate Mode GUIs works. The Immediate Mode GUI paradigm may at first appear unusual to some users. This is mainly because "Retained Mode" GUIs have been so widespread and predominant. The following links can give you a better understanding about how Immediate Mode GUIs works.
- [Johannes 'johno' Norneby's article](http://www.johno.se/book/imgui.html). - [Johannes 'johno' Norneby's article](http://www.johno.se/book/imgui.html).
- [A presentation by Rickard Gustafsson and Johannes Algelind](http://www.cse.chalmers.se/edu/year/2011/course/TDA361/Advanced%20Computer%20Graphics/IMGUI.pdf). - [A presentation by Rickard Gustafsson and Johannes Algelind](http://www.cse.chalmers.se/edu/year/2011/course/TDA361/Advanced%20Computer%20Graphics/IMGUI.pdf).
- [Jari Komppa's tutorial on building an ImGui library](http://iki.fi/sol/imgui/). - [Jari Komppa's tutorial on building an IMGUI library](http://iki.fi/sol/imgui/).
- [Casey Muratori's original video that popularized the concept](https://mollyrocket.com/861). - [Casey Muratori's original video that popularized the concept](https://mollyrocket.com/861).
- [Nicolas Guillemot's CppCon'16 flash-talk about Dear ImGui](https://www.youtube.com/watch?v=LSRJ1jZq90k). - [Nicolas Guillemot's CppCon'16 flash-talk about Dear ImGui](https://www.youtube.com/watch?v=LSRJ1jZq90k).
- [Thierry Excoffier's Zero Memory Widget](http://perso.univ-lyon1.fr/thierry.excoffier/ZMW/). - [Thierry Excoffier's Zero Memory Widget](http://perso.univ-lyon1.fr/thierry.excoffier/ZMW/).
See the [Wiki](https://github.com/ocornut/imgui/wiki) for more references and [Bindings](https://github.com/ocornut/imgui/wiki/Bindings) for third-party bindings to different languages and frameworks. See the [Wiki](https://github.com/ocornut/imgui/wiki) for more references and [Bindings](https://github.com/ocornut/imgui/wiki/Bindings) for third-party bindings to different languages and frameworks.
Support Forums Support
-------------- -------
If you have issues with: compiling, linking, adding fonts, running or displaying Dear ImGui, or wiring inputs: please post on the Discourse forums: https://discourse.dearimgui.org. If you are new to Dear ImGui and have issues with: compiling, linking, adding fonts, wiring inputs, running or displaying Dear ImGui: please post on the Discourse forums: https://discourse.dearimgui.org.
For any other questions, bug reports, requests, feedback, you may post on https://github.com/ocornut/imgui/issues. Please read and fill the New Issue template carefully. Otherwise for any other questions, bug reports, requests, feedback, you may post on https://github.com/ocornut/imgui/issues. Please read and fill the New Issue template carefully.
Private support is available for paying customers.
Frequently Asked Question (FAQ) Frequently Asked Question (FAQ)
------------------------------- -------------------------------
**Where is the documentation?** **Where is the documentation?**
- The documentation is at the top of imgui.cpp + effectively imgui.h. This library is poorly documented at the moment and expects of the user to be acquainted with C/C++.
- Example code is in imgui_demo.cpp and particularly the ImGui::ShowDemoWindow() function. It covers most features of ImGui so you can read the code and call the function itself to see its output. - Run the examples/ applications and explore them.
- Standalone example applications using e.g. OpenGL/DirectX are provided in the examples/ folder. - See demo code in imgui_demo.cpp and particularly the ImGui::ShowDemoWindow() function.
- We obviously needs better documentation! Consider contributing or becoming a [Patron](http://www.patreon.com/imgui) to promote this effort. - The demo covers most features of Dear ImGui, so you can read the code and see its output.
- See documentation and comments at the top of imgui.cpp + effectively imgui.h.
- Dozens of standalone example applications using e.g. OpenGL/DirectX are provided in the examples/ folder to explain how to integrate Dear ImGui with your own engine/application.
- Your programming IDE is your friend, find the type or function declaration to find comments associated to it. - Your programming IDE is your friend, find the type or function declaration to find comments associated to it.
- We obviously needs better documentation! Consider contributing or becoming a [Patron](http://www.patreon.com/imgui) to promote this effort.
**Which version should I get?** **Which version should I get?**
I occasionally tag [Releases](https://github.com/ocornut/imgui/releases) but it is generally safe and recommended to sync to master/latest. The library is fairly stable and regressions tend to be fixed fast when reported. I occasionally tag [Releases](https://github.com/ocornut/imgui/releases) but it is generally safe and recommended to sync to master/latest. The library is fairly stable and regressions tend to be fixed fast when reported.
You may also peak at the [Multi-Viewport](https://github.com/ocornut/imgui/issues/1542) and [Docking](https://github.com/ocornut/imgui/issues/2109) branches. Even though they are marked beta, several projects are using them and they are kept in sync with master regularly. You may also peak at the [Multi-Viewport](https://github.com/ocornut/imgui/issues/1542) and [Docking](https://github.com/ocornut/imgui/issues/2109) features in the `docking` branch. Many projects are using this branch and it is kept in sync with master regularly.
**Who uses Dear ImGui?** **Who uses Dear ImGui?**
See the [Quotes](https://github.com/ocornut/imgui/wiki/Quotes) and [Software using dear imgui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) pages for an (incomplete) list of games/software which are publicly known to use dear imgui. Please add yours if you can! See the [Quotes](https://github.com/ocornut/imgui/wiki/Quotes) and [Software using dear imgui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) Wiki pages for a list of games/software which are publicly known to use dear imgui. Please add yours if you can!
**Why the odd dual naming, "Dear ImGui" vs "ImGui"?** **Why the odd dual naming, "Dear ImGui" vs "ImGui"?**
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 as "ImGui" due to the fact that I didn't give it a proper name when I released 1.0 and had no particular expectation that it would take off. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations (e.g. Unity uses it own implementation of the IMGUI paradigm). To reduce this 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. Please try to refer to this library as "Dear ImGui".
**How can I tell whether to dispatch mouse/keyboard to imgui or to my application?** **How can I tell whether to dispatch mouse/keyboard to Dear ImGui or to my application?**
<br>**How can I display an image? What is ImTextureID, how does it works?** <br>**How can I display an image? What is ImTextureID, how does it works?**
<br>**How can I have multiple widgets with the same label or with an empty label? A primer on labels and the ID Stack.** <br>**Why are multiple widgets reacting when I interact with a single one? How can I have multiple widgets with the same label or with an empty label? A primer on labels and the ID Stack...**
<br>**How can I use my own math types instead of ImVec2/ImVec4?** <br>**How can I use my own math types instead of ImVec2/ImVec4?**
<br>**How can I load a different font than the default?** <br>**How can I load a different font than the default?**
<br>**How can I easily use icons in my application?** <br>**How can I easily use icons in my application?**
<br>**How can I load multiple fonts?** <br>**How can I load multiple fonts?**
<br>**How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?** ([example](https://github.com/ocornut/imgui/wiki/Loading-Font-Example)) <br>**How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?** ([example](https://github.com/ocornut/imgui/wiki/Loading-Font-Example))
<br>**How can I interact with standard C++ types (such as std::string and std::vector)?** <br>**How can I interact with standard C++ types (such as std::string and std::vector)?**
<br>**How can I use the drawing facilities without an Dear ImGui window? (using ImDrawList API)** <br>**How can I use the drawing facilities without a Dear ImGui window? (using ImDrawList API)**
<br>**How can I use this without a mouse, without a keyboard or without a screen? (gamepad, input share, remote display)** <br>**How can I use this without a mouse, without a keyboard or without a screen? (gamepad, input share, remote display)**
<br>**I integrated Dear ImGui in my engine and the text or lines are blurry..** <br>**I integrated Dear ImGui in my engine and the text or lines are blurry..**
<br>**I integrated Dear ImGui in my engine and some elements are disappearing when I move windows around..** <br>**I integrated Dear ImGui in my engine and some elements are disappearing when I move windows around..**
<br>**How can I help?** <br>**How can I help?**
See the FAQ in imgui.cpp for answers. See the FAQ in [imgui.cpp](https://github.com/ocornut/imgui/blob/master/imgui.cpp) for answers.
**Can you create elaborate/serious tools with Dear ImGui?** **Can you create elaborate/serious tools with Dear ImGui?**
@ -269,7 +275,7 @@ You can alter the look of the interface to some degree: changing colors, sizes,
Dear ImGui takes advantage of a few C++ languages features for convenience but nothing anywhere Boost-insanity/quagmire. Dear ImGui does NOT require C++11 so it can be used with most old C++ compilers. Dear ImGui doesn't use any C++ header file. Language-wise, 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. Dear ImGui takes advantage of a few C++ languages features for convenience but nothing anywhere Boost-insanity/quagmire. Dear ImGui does NOT require C++11 so it can be used with most old C++ compilers. Dear ImGui doesn't use any C++ header file. Language-wise, 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.
There is an auto-generated [c-api for Dear ImGui (cimgui)](https://github.com/cimgui/cimgui) by Sonoro1234 and Stephan Dilly. This is designed for binding other languages. If possible, I would suggest using your target language functionalities to try replicating the function overloading and default parameters used in C++ else the API may be harder to use. Also see [Bindings](https://github.com/ocornut/imgui/wiki/Bindings) for third-party bindings to other languages. There is an auto-generated [c-api for Dear ImGui (cimgui)](https://github.com/cimgui/cimgui) by Sonoro1234 and Stephan Dilly. It is designed for creating binding to other languages. If possible, I would suggest using your target language functionalities to try replicating the function overloading and default parameters used in C++ else the API may be harder to use. Also see [Bindings](https://github.com/ocornut/imgui/wiki/Bindings) for various third-party bindings.
Support dear imgui Support dear imgui
------------------ ------------------
@ -279,7 +285,7 @@ Support dear imgui
- You may participate in the [Discourse forums](https://discourse.dearimgui.org) and the GitHub [issues tracker](https://github.com/ocornut/imgui/issues). - You may participate in the [Discourse forums](https://discourse.dearimgui.org) and the GitHub [issues tracker](https://github.com/ocornut/imgui/issues).
- You may help with development and submit pull requests! Please understand that by submitting a PR you are also submitting a request for the maintainer to review your code and then take over its maintenance forever. PR should be crafted both in the interest in the end-users and also to ease the maintainer into understanding and accepting it. - You may help with development and submit pull requests! Please understand that by submitting a PR you are also submitting a request for the maintainer to review your code and then take over its maintenance forever. PR should be crafted both in the interest in the end-users and also to ease the maintainer into understanding and accepting it.
- See [Help wanted](https://github.com/ocornut/imgui/wiki/Help-Wanted) on the [Wiki](https://github.com/ocornut/imgui/wiki/) for some more ideas. - See [Help wanted](https://github.com/ocornut/imgui/wiki/Help-Wanted) on the [Wiki](https://github.com/ocornut/imgui/wiki/) for some more ideas.
- Convince your company to financially support this project. - Have your company financially support this project.
**How can I help financing further development of Dear ImGui?** **How can I help financing further development of Dear ImGui?**
@ -289,26 +295,26 @@ Individuals/hobbyists: support continued maintenance and development via the mon
<br>&nbsp;&nbsp;[![Patreon](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/patreon_01.png)](http://www.patreon.com/imgui) <br>&nbsp;&nbsp;[![Patreon](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/patreon_01.png)](http://www.patreon.com/imgui)
Individuals/hobbyists: support continued maintenance and development via PayPal: Individuals/hobbyists: support continued maintenance and development via PayPal:
<br>&nbsp;&nbsp;[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U) <br>&nbsp;&nbsp;[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WGHNC6MBFLZ2S)
Businesses: support continued maintenance and development via support contracts or sponsoring: Businesses: support continued maintenance and development via support contracts or sponsoring:
<br>&nbsp;&nbsp;_E-mail: omarcornut at gmail dot com_ <br>&nbsp;&nbsp;_E-mail: omarcornut at gmail dot com_
Ongoing dear imgui development is financially supported by users and private sponsors (past and present): Ongoing dear imgui development is financially supported by users and private sponsors, recently:
**Platinum-chocolate sponsors** **Platinum-chocolate sponsors**
- **Blizzard Entertainment**. - **Blizzard Entertainment**.
**Double-chocolate sponsors** **Double-chocolate sponsors**
- Media Molecule, Mobigame, Insomniac Games, Aras Pranckevičius, Lizardcube, Greggman, DotEmu, Nadeo, Supercell, Runner, Aiden Koss, Kylotonn. - Media Molecule, Mobigame, Aras Pranckevičius, Greggman, DotEmu, Nadeo, Supercell, Runner, Aiden Koss, Kylotonn.
**Salty caramel supporters** **Salty caramel supporters**
- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko, Mercury Labs, Singularity Demo Group, Mischa Alff, Sebastien Ronsse, Lionel Landwerlin, Nikolay Ivanov, Ron Gilbert, Brandon Townsend, Nikhil Deshpande, Cort Stratton, drudru, Harfang 3D, Jeff Roberts, Rainway inc. - Remedy Entertainment, Recognition Robotics, ikrima, Geoffrey Evans, Mercury Labs, Singularity Demo Group, Lionel Landwerlin, Ron Gilbert, Brandon Townsend, Nikhil Deshpande, Cort Stratton, drudru, Harfang 3D, Jeff Roberts, Rainway inc, Ondra Voves, Mesh Consultants, Unit 2 Games, Neil Bickford.
**Caramel supporters** **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, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, Kit framework, Josh Faust, Martin Donlon, Quinton, Felix, Andrew Belt, Codecat, Cort Stratton, Claudio Canepa, Doug McNabb, Emmanuel Julien, Guillaume Chereau, Jeffrey Slutter, Jeremiah Deckard, r-lyeh, Roger Clark, Nekith, Joshua Fisher, Malte Hoffmann, Mustafa Karaalioglu, Merlyn Morgan-Graham, Per Vognsen, Fabian Giesen, Jan Staubach, Matt Hargett, John Shearer, Jesse Chounard, kingcoopa, Miloš Tošić, Jonas Bernemann, Johan Andersson, Nathan Hartman, Michael Labbe, Tomasz Golebiowski, Louis Schnellbach, Felipe Alfonso, Jimmy Andrews, Bojan Endrovski, Robin Berg Pettersen, Rachel Crawford, Edsel Malasig, Andrew Johnson, Sean Hunter, Jordan Mellow, Nefarius Software Solutions, Laura Wieme, Robert Nix, Mick Honey, Astrofra, Jonas Lehmann, Steven Kah Hien Wong, Bartosz Bielecki, Oscar Penas, A M, Liam Moynihan, Artometa, Mark Lee, Dimitri Diakopoulos. - Jerome Lanquetot, Daniel Collin, Ctrl Alt Ninja, Neil Henning, Neil Blakey-Milner, Aleksei, NeiloGD, Eric, Game Atelier, Vincent Hamm, Colin Riley, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, Josh Faust, Martin Donlon, Codecat, Doug McNabb, Emmanuel Julien, Guillaume Chereau, Jeffrey Slutter, Jeremiah Deckard, r-lyeh, Nekith, Joshua Fisher, Malte Hoffmann, Mustafa Karaalioglu, Merlyn Morgan-Graham, Per Vognsen, Fabian Giesen, Jan Staubach, Matt Hargett, John Shearer, Jesse Chounard, kingcoopa, Jonas Bernemann, Johan Andersson, Michael Labbe, Tomasz Golebiowski, Louis Schnellbach, Jimmy Andrews, Bojan Endrovski, Robin Berg Pettersen, Rachel Crawford, Andrew Johnson, Sean Hunter, Jordan Mellow, Nefarius Software Solutions, Laura Wieme, Robert Nix, Mick Honey, Steven Kah Hien Wong, Bartosz Bielecki, Oscar Penas, A M, Liam Moynihan, Artometa, Mark Lee, Dimitri Diakopoulos, Pete Goodwin, Johnathan Roatch, nyu lea, Oswald Hurlem, Semyon Smelyanskiy, Le Bach, Jeong MyeongSoo, Chris Matthews, Astrofra.
And all other supporters; THANK YOU! And all other past and present supporters; THANK YOU!
(Please contact me if you would like to be added or removed from this list) (Please contact me if you would like to be added or removed from this list)
Credits Credits
@ -316,7 +322,7 @@ Credits
Developed by [Omar Cornut](http://www.miracleworld.net) and every direct or indirect contributors to the GitHub. The early version of this library was developed with the support of [Media Molecule](http://www.mediamolecule.com) and first used internally on the game [Tearaway](http://tearaway.mediamolecule.com). Developed by [Omar Cornut](http://www.miracleworld.net) and every direct or indirect contributors to the GitHub. The early version of this library was developed with the support of [Media Molecule](http://www.mediamolecule.com) and first used internally on the game [Tearaway](http://tearaway.mediamolecule.com).
I first discovered the IMGUI paradigm at [Q-Games](http://www.q-games.com) where Atman had dropped his own simple implementation in the codebase, which I spent quite some time improving and thinking about. It turned out that Atman was exposed to the concept directly by working with Casey. When I moved to Media Molecule I rewrote a new library trying to overcome the flaws and limitations of the first one I've worked with. It became this library and since then I have spent an unreasonable amount of time iterating on it. I first discovered the IMGUI paradigm at [Q-Games](http://www.q-games.com) where Atman Binstock had dropped his own simple implementation in the codebase, which I spent quite some time improving and thinking about. It turned out that Atman was exposed to the concept directly by working with Casey. When I moved to Media Molecule I rewrote a new library trying to overcome the flaws and limitations of the first one I've worked with. It became this library and since then I have spent an unreasonable amount of time iterating and improving it.
Embeds [ProggyClean.ttf](http://upperbounds.net) font by Tristan Grimmer (MIT license). Embeds [ProggyClean.ttf](http://upperbounds.net) font by Tristan Grimmer (MIT license).
@ -327,4 +333,4 @@ Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Bin
License License
------- -------
Dear ImGui is licensed under the MIT License, see LICENSE for more information. Dear ImGui is licensed under the MIT License, see [LICENSE.txt](https://github.com/ocornut/imgui/blob/master/LICENSE.txt) for more information.

View File

@ -9,6 +9,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- doc/test: checklist app to verify binding/integration of imgui (test inputs, rendering, callback, etc.). - doc/test: checklist app to verify binding/integration of imgui (test inputs, rendering, callback, etc.).
- doc/tips: tips of the day: website? applet in imgui_club? - doc/tips: tips of the day: website? applet in imgui_club?
- window: preserve/restore relative focus ordering (persistent or not) (#2304) -> also see docking reference to same #.
- window: calling SetNextWindowSize() every frame with <= 0 doesn't do anything, may be useful to allow (particularly when used for a single axis). (#690) - window: calling SetNextWindowSize() every frame with <= 0 doesn't do anything, may be useful to allow (particularly when used for a single axis). (#690)
- window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. perhaps a lightweight explicit cleanup pass. - window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. perhaps a lightweight explicit cleanup pass.
- window: auto-fit feedback loop when user relies on any dynamic layout (window width multiplier, column) appears weird to end-user. clarify. - window: auto-fit feedback loop when user relies on any dynamic layout (window width multiplier, column) appears weird to end-user. clarify.
@ -25,27 +26,33 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- window: using SetWindowPos() inside Begin() and moving the window with the mouse reacts a very ugly glitch. We should just defer the SetWindowPos() call. - window: using SetWindowPos() inside Begin() and moving the window with the mouse reacts a very ugly glitch. We should just defer the SetWindowPos() call.
- window: GetWindowSize() returns (0,0) when not calculated? (#1045) - window: GetWindowSize() returns (0,0) when not calculated? (#1045)
- window: investigate better auto-positioning for new windows. - window: investigate better auto-positioning for new windows.
- window/opt: freeze window flag: if not focused/hovered, return false, render with previous ImDrawList. and/or reduce refresh rate. - window: top most window flag? (#2574)
- window/opt: freeze window flag: if not focused/hovered, return false, render with previous ImDrawList. and/or reduce refresh rate. -> this may require enforcing that it is illegal to submit contents if Begin returns false.
- window/child: the first draw command of a child window could be moved into the current draw command of the parent window (unless child+tooltip?). - window/child: the first draw command of a child window could be moved into the current draw command of the parent window (unless child+tooltip?).
- window/child: border could be emitted in parent as well.
- window/clipping: some form of clipping when DisplaySize (or corresponding viewport) is zero. - window/clipping: some form of clipping when DisplaySize (or corresponding viewport) is zero.
- window/tab: add a way to signify that a window or docked window requires attention (e.g. blinking title bar).
- scrolling: while holding down a scrollbar, try to keep the same contents visible (at least while not moving mouse) - scrolling: while holding down a scrollbar, try to keep the same contents visible (at least while not moving mouse)
- scrolling: allow immediately effective change of scroll after Begin() if we haven't appended items yet. - scrolling: allow immediately effective change of scroll after Begin() if we haven't appended items yet.
- scrolling/clipping: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y). (2017-08-20: can't repro) - scrolling/clipping: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y). (2017-08-20: can't repro)
- scrolling/style: shadows on scrollable areas to denote that there is more contents - scrolling/style: shadows on scrollable areas to denote that there is more contents
- drawdata: make it easy to clone (or swap?) a ImDrawData so user can easily save that data if they use threaded rendering. - drawdata: make it easy to clone (or swap?) a ImDrawData so user can easily save that data if they use threaded rendering.
! drawlist: add calctextsize func to facilitate consistent code from user pov (currently need to use ImGui or ImFont alternatives!)
- drawlist: end-user probably can't call Clear() directly because we expect a texture to be pushed in the stack. - drawlist: end-user probably can't call Clear() directly because we expect a texture to be pushed in the stack.
- drawlist: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command). - drawlist: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command).
- drawlist: primitives/helpers to manipulate vertices post submission, so e.g. a quad/rect can be resized to fit later submitted content, _without_ using the ChannelSplit api - drawlist: primitives/helpers to manipulate vertices post submission, so e.g. a quad/rect can be resized to fit later submitted content, _without_ using the ChannelSplit api
- drawlist: make it easier to toggle AA per primitive, so we can use e.g. non-AA fill + AA borders more naturally - drawlist: make it easier to toggle AA per primitive, so we can use e.g. non-AA fill + AA borders more naturally
- drawlist: non-AA strokes have gaps between points (#593, #288), especially RenderCheckmark(). - drawlist: non-AA strokes have gaps between points (#593, #288), glitch especially on RenderCheckmark() and ColorPicker4().
- drawlist: would be good to be able to deep copy of ImDrawData (we have a deep copy of ImDrawList now). - drawlist: would be good to be able to deep copy of ImDrawData (we have a deep copy of ImDrawList now).
- drawlist: rendering: provide a way for imgui to output to a single/global vertex buffer, re-order indices only at the end of the frame (ref: https://gist.github.com/floooh/10388a0afbe08fce9e617d8aefa7d302) - drawlist: rendering: provide a way for imgui to output to a single/global vertex buffer, re-order indices only at the end of the frame (ref: https://gist.github.com/floooh/10388a0afbe08fce9e617d8aefa7d302)
- drawlist: callback: add an extra void* in ImDrawCallback to allow passing render-local data to the callback (would break API). - drawlist: callback: add an extra void* in ImDrawCallback to allow passing render-local data to the callback (would break API).
- drawlist: AddRect vs AddLine position confusing (#2441)
- drawlist: channel splitter should be external helper and not stored in ImDrawList.
- drawlist/opt: store rounded corners in texture to use 1 quad per corner (filled and wireframe) to lower the cost of rounding. (#1962) - drawlist/opt: store rounded corners in texture to use 1 quad per corner (filled and wireframe) to lower the cost of rounding. (#1962)
- drawlist/opt: AddRect() axis aligned pixel aligned (no-aa) could use 8 triangles instead of 16 and no normal calculation. - drawlist/opt: AddRect() axis aligned pixel aligned (no-aa) could use 8 triangles instead of 16 and no normal calculation.
- drawlist/opt: thick AA line could be doable in same number of triangles as 1.0 AA line by storing gradient+full color in atlas.
- main: considering adding an Init() function? some constructs are awkward in the implementation because of the lack of them.
- main: find a way to preserve relative orders of multiple reappearing windows (so an app toggling between "modes" e.g. fullscreen vs all tools) won't lose relative ordering. - main: find a way to preserve relative orders of multiple reappearing windows (so an app toggling between "modes" e.g. fullscreen vs all tools) won't lose relative ordering.
- main: IsItemHovered() make it more consistent for various type of widgets, widgets with multiple components, etc. also effectively IsHovered() region sometimes differs from hot region, e.g tree nodes - main: IsItemHovered() make it more consistent for various type of widgets, widgets with multiple components, etc. also effectively IsHovered() region sometimes differs from hot region, e.g tree nodes
- main: IsItemHovered() info stored in a stack? so that 'if TreeNode() { Text; TreePop; } if IsHovered' return the hover state of the TreeNode? - main: IsItemHovered() info stored in a stack? so that 'if TreeNode() { Text; TreePop; } if IsHovered' return the hover state of the TreeNode?
@ -54,11 +61,16 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- widgets: display mode: widget-label, label-widget (aligned on column or using fixed size), label-newline-tab-widget etc. (#395) - widgets: display mode: widget-label, label-widget (aligned on column or using fixed size), label-newline-tab-widget etc. (#395)
- widgets: clean up widgets internal toward exposing everything and stabilizing imgui_internals.h. - widgets: clean up widgets internal toward exposing everything and stabilizing imgui_internals.h.
- widgets: add visuals for Disabled/ReadOnly mode and expose publicly (#211) - widgets: add visuals for Disabled/ReadOnly mode and expose publicly (#211)
- widgets: add always-allow-overlap mode. - widgets: add always-allow-overlap mode. This should perhaps be the default.
- widgets: start exposing PushItemFlag() and ImGuiItemFlags - widgets: start exposing PushItemFlag() and ImGuiItemFlags
- widgets: alignment options in style (e.g. center Selectable, Right-Align within Button, etc.) #1260 - widgets: alignment options in style (e.g. center Selectable, Right-Align within Button, etc.) #1260
- widgets: activate by identifier (trigger button, focus given id) - widgets: activate by identifier (trigger button, focus given id)
- widgets: a way to represent "mixed" values, so e.g. all values replaced with **, including check-boxes, colors, etc. with support for multi-components widgets (e.g. SliderFloat3, make only "Y" mixed) - widgets: a way to represent "mixed" values, so e.g. all values replaced with **, including check-boxes, colors, etc. with support for multi-components widgets (e.g. SliderFloat3, make only "Y" mixed)
- widgets: selectable: generic BeginSelectable()/EndSelectable() mechanism.
- widgets: selectable: a way to visualize partial/mixed selection (e.g. parent tree node has children with mixed selection)
- widgets: checkbox: checkbox with custom glyph inside frame.
- widgets: coloredit: keep reporting as active when picker is on?
- widgets: group/scalarn functions: expose more per-component information. e.g. store NextItemData.ComponentIdx set by scalarn function, groups can expose them back somehow.
- input text: clean up the mess caused by converting UTF-8 <> wchar. the code is rather inefficient right now and super fragile. - input text: clean up the mess caused by converting UTF-8 <> wchar. the code is rather inefficient right now and super fragile.
- input text: reorganize event handling, allow CharFilter to modify buffers, allow multiple events? (#541) - input text: reorganize event handling, allow CharFilter to modify buffers, allow multiple events? (#541)
@ -72,8 +84,12 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- input text: add discard flag (e.g. ImGuiInputTextFlags_DiscardActiveBuffer) or make it easier to clear active focus for text replacement during edition (#725) - input text: add discard flag (e.g. ImGuiInputTextFlags_DiscardActiveBuffer) or make it easier to clear active focus for text replacement during edition (#725)
- input text: display bug when clicking a drag/slider after an input text in a different window has all-selected text (order dependent). actually a very old bug but no one appears to have noticed it. - input text: display bug when clicking a drag/slider after an input text in a different window has all-selected text (order dependent). actually a very old bug but no one appears to have noticed it.
- input text: allow centering/positioning text so that ctrl+clicking Drag or Slider keeps the textual value at the same pixel position. - input text: allow centering/positioning text so that ctrl+clicking Drag or Slider keeps the textual value at the same pixel position.
- input text: what's the easiest way to implement a nice IP/Mac address input editor? - input text: decorrelate layout from inputs - e.g. what's the easiest way to implement a nice IP/Mac address input editor?
- input text: Global callback system so user can plug in an expression evaluator easily. - input text: global callback system so user can plug in an expression evaluator easily. (#1691)
- input text: force scroll to end or scroll to a given line/contents (so user can implement a log or a search feature)
- input text: a side bar that could e.g. preview where errors are. probably left to the user to draw but we'd need to give them the info there.
- input text: a way for the user to provide syntax coloring.
- input text: Shift+TAB with ImGuiInputTextFlags_AllowTabInput could eat preceding blanks, up to tab_count.
- input text multi-line: don't directly call AddText() which does an unnecessary vertex reserve for character count prior to clipping. and/or more line-based clipping to AddText(). and/or reorganize TextUnformatted/RenderText for more efficiency for large text (e.g TextUnformatted could clip and log separately, etc). - input text multi-line: don't directly call AddText() which does an unnecessary vertex reserve for character count prior to clipping. and/or more line-based clipping to AddText(). and/or reorganize TextUnformatted/RenderText for more efficiency for large text (e.g TextUnformatted could clip and log separately, etc).
- input text multi-line: support for cut/paste without selection (cut/paste the current line) - input text multi-line: support for cut/paste without selection (cut/paste the current line)
- input text multi-line: line numbers? status bar? (follow up on #200) - input text multi-line: line numbers? status bar? (follow up on #200)
@ -91,9 +107,12 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- layout: horizontal flow until no space left (#404) - layout: horizontal flow until no space left (#404)
- layout: more generic alignment state (left/right/centered) for single items? - layout: more generic alignment state (left/right/centered) for single items?
- layout: clean up the InputFloatN/SliderFloatN/ColorEdit4 layout code. item width should include frame padding. - layout: clean up the InputFloatN/SliderFloatN/ColorEdit4 layout code. item width should include frame padding.
- layout: BeginGroup() needs a border option. (~#1496)
- layout: vertical alignment of mixed height items (e.g. buttons) within a same line (#1284) - layout: vertical alignment of mixed height items (e.g. buttons) within a same line (#1284)
- group: BeginGroup() needs a border option. (~#1496)
- group: IsHovered() after EndGroup() covers whole aabb rather than the intersection of individual items. Is that desirable?
- group: merge deactivation/activation within same group (fwd WasEdited flag). (#2550)
- columns: sizing policy (e.g. for each column: fixed size, %, fill, distribute default size among fills) (#513, #125) - columns: sizing policy (e.g. for each column: fixed size, %, fill, distribute default size among fills) (#513, #125)
- columns: add a conditional parameter to SetColumnOffset() (#513, #125) - columns: add a conditional parameter to SetColumnOffset() (#513, #125)
- columns: headers. re-orderable. (#513, #125) - columns: headers. re-orderable. (#513, #125)
@ -120,8 +139,11 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- clipper: ability to force display 1 item in the list would be convenient (for patterns where we need to set active id etc.) - clipper: ability to force display 1 item in the list would be convenient (for patterns where we need to set active id etc.)
- clipper: ability to disable the clipping through a simple flag/bool. - clipper: ability to disable the clipping through a simple flag/bool.
- clipper: ability to run without knowing full count in advance. - clipper: ability to run without knowing full count in advance.
- clipper: horizontal clipping support. (#2580)
- splitter/separator: formalize the splitter idiom into an official api (we want to handle n-way split) (#319) - separator: expose flags (#759)
- separator: width, thickness, centering (#1643)
- splitter: formalize the splitter idiom into an official api (we want to handle n-way split) (#319)
- dock: merge docking branch (#2109) - dock: merge docking branch (#2109)
- dock: dock out from a collapsing header? would work nicely but need emitting window to keep submitting the code. - dock: dock out from a collapsing header? would work nicely but need emitting window to keep submitting the code.
@ -129,12 +151,11 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- tabs: make EndTabBar fail if users doesn't respect BeginTabBar return value, for consistency/future-proofing. - tabs: make EndTabBar fail if users doesn't respect BeginTabBar return value, for consistency/future-proofing.
- tabs: persistent order/focus in BeginTabBar() api (#261, #351) - tabs: persistent order/focus in BeginTabBar() api (#261, #351)
- ext: stl-ish friendly extension (imgui_stl.h) that has wrapper for std::string, std::vector etc.
- button: provide a button that looks framed. (?) - button: provide a button that looks framed. (?)
- image/image button: misalignment on padded/bordered button? - image/image button: misalignment on padded/bordered button?
- image/image button: parameters are confusing, image() has tint_col,border_col whereas imagebutton() has bg_col/tint_col. Even thou they are different parameters ordering could be more consistent. can we fix that? - image/image button: parameters are confusing, image() has tint_col,border_col whereas imagebutton() has bg_col/tint_col. Even thou they are different parameters ordering could be more consistent. can we fix that?
- image button: not taking an explicit id is odd. - image button: not taking an explicit id can be problematic. (#2464, #1390)
- slider/drag: ctrl+click when format doesn't include a % character.. disable? display underlying value in default format? (see TempInputTextScalar)
- slider: allow using the [-]/[+] buttons used by InputFloat()/InputInt() - slider: allow using the [-]/[+] buttons used by InputFloat()/InputInt()
- slider: initial absolute click is imprecise. change to relative movement slider (same as scrollbar). (#1946) - slider: initial absolute click is imprecise. change to relative movement slider (same as scrollbar). (#1946)
- slider: add dragging-based widgets to edit values with mouse (on 2 axises), saving screen real-estate. - slider: add dragging-based widgets to edit values with mouse (on 2 axises), saving screen real-estate.
@ -145,7 +166,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- knob: rotating knob widget (#942) - knob: rotating knob widget (#942)
- drag float: power/logarithmic slider and drags are weird. (#1316) - drag float: power/logarithmic slider and drags are weird. (#1316)
- drag float: up/down axis - drag float: up/down axis
- drag float: power != 0.0f with current value being outside the the range keeps the value stuck. - drag float: power != 0.0f with current value being outside the range keeps the value stuck.
- drag float: added leeway on edge (e.g. a few invisible steps past the clamp limits) - drag float: added leeway on edge (e.g. a few invisible steps past the clamp limits)
- combo: use clipper: make it easier to disable clipper with a single flag. - combo: use clipper: make it easier to disable clipper with a single flag.
@ -159,7 +180,9 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- listbox: user may want to initial scroll to focus on the one selected value? - listbox: user may want to initial scroll to focus on the one selected value?
- listbox: expose hovered item for a basic ListBox - listbox: expose hovered item for a basic ListBox
- listbox: keyboard navigation. - listbox: keyboard navigation.
- listbox: disable capturing mouse wheel if the listbox has no scrolling. (#1681)
- listbox: scrolling should track modified selection. - listbox: scrolling should track modified selection.
- listbox: future api should allow to enable horizontal scrolling (#2510)
!- popups/menus: clarify usage of popups id, how MenuItem/Selectable closing parent popups affects the ID, etc. this is quite fishy needs improvement! (#331, #402) !- popups/menus: clarify usage of popups id, how MenuItem/Selectable closing parent popups affects the ID, etc. this is quite fishy needs improvement! (#331, #402)
- popups/modal: make modal title bar blink when trying to click outside the modal - popups/modal: make modal title bar blink when trying to click outside the modal
@ -187,6 +210,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- text wrapped: figure out better way to use TextWrapped() in an always auto-resize context (tooltip, etc.) (#249) - text wrapped: figure out better way to use TextWrapped() in an always auto-resize context (tooltip, etc.) (#249)
- text: it's currently impossible to have a window title with "##". perhaps an official workaround would be nice. \ style inhibitor? non-visible ascii code to insert between #? - text: it's currently impossible to have a window title with "##". perhaps an official workaround would be nice. \ style inhibitor? non-visible ascii code to insert between #?
- text: provided a framed text helper, e.g. https://pastebin.com/1Laxy8bT - text: provided a framed text helper, e.g. https://pastebin.com/1Laxy8bT
- text: refactor TextUnformatted (or underlying function) to more explicitly request if we need width measurement or not
- text link/url button: underlined. should api expose an ID or use text contents as ID? which colors enum to use? - text link/url button: underlined. should api expose an ID or use text contents as ID? which colors enum to use?
- tree node / optimization: avoid formatting when clipped. - tree node / optimization: avoid formatting when clipped.
@ -196,6 +220,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- tree node / selectable render mismatch which is visible if you use them both next to each other (e.g. cf. property viewer) - tree node / selectable render mismatch which is visible if you use them both next to each other (e.g. cf. property viewer)
- tree node: tweak color scheme to distinguish headers from selected tree node (#581) - tree node: tweak color scheme to distinguish headers from selected tree node (#581)
- tree node: leaf/non-leaf highlight mismatch. - tree node: leaf/non-leaf highlight mismatch.
- tree node: _NoIndentOnOpen flag? would require to store a per-depth bit mask to store info for pop (or whatever is cheaper)
- settings: write more decent code to allow saving/loading new fields: columns, selected tree nodes? - settings: write more decent code to allow saving/loading new fields: columns, selected tree nodes?
- settings: api for per-tool simple persistent data (bool,int,float,columns sizes,etc.) in .ini file (#437) - settings: api for per-tool simple persistent data (bool,int,float,columns sizes,etc.) in .ini file (#437)
@ -208,29 +233,36 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- style: a concept of "compact style" that the end-user can easily rely on (e.g. PushStyleCompact()?) that maps to other settings? avoid implementing duplicate helpers such as SmallCheckbox(), etc. - style: a concept of "compact style" that the end-user can easily rely on (e.g. PushStyleCompact()?) that maps to other settings? avoid implementing duplicate helpers such as SmallCheckbox(), etc.
- style: try to make PushStyleVar() more robust to incorrect parameters (to be more friendly to edit & continues situation). - style: try to make PushStyleVar() more robust to incorrect parameters (to be more friendly to edit & continues situation).
- style: global scale setting. - style: global scale setting.
- style: FramePadding could be different for up vs down (#584)
- style: WindowPadding needs to be EVEN as the 0.5 multiplier used on this value probably have a subtle effect on clip rectangle - style: WindowPadding needs to be EVEN as the 0.5 multiplier used on this value probably have a subtle effect on clip rectangle
- style: have a more global HSV setter (e.g. alter hue on all elements). consider replacing active/hovered by offset in HSV space? (#438, #707, #1223) - style: have a more global HSV setter (e.g. alter hue on all elements). consider replacing active/hovered by offset in HSV space? (#438, #707, #1223)
- style: gradients fill (#1223) ~ 2 bg colors for each fill? tricky with rounded shapes and using textures for corners. - style: gradients fill (#1223) ~ 2 bg colors for each fill? tricky with rounded shapes and using textures for corners.
- style editor: color child window height expressed in multiple of line height. - style editor: color child window height expressed in multiple of line height.
- log: LogButtons() options for specifying depth and/or hiding depth slider
- log: have more control over the log scope (e.g. stop logging when leaving current tree node scope) - log: have more control over the log scope (e.g. stop logging when leaving current tree node scope)
- log: be able to log anything (e.g. right-click on a window/tree-node, shows context menu? log into tty/file/clipboard) - log: be able to log anything (e.g. right-click on a window/tree-node, shows context menu? log into tty/file/clipboard)
- log: let user copy any window content to clipboard easily (CTRL+C on windows? while moving it? context menu?). code is commented because it fails with multiple Begin/End pairs. - log: let user copy any window content to clipboard easily (CTRL+C on windows? while moving it? context menu?). code is commented because it fails with multiple Begin/End pairs.
- log: obsolete LogButtons() all together.
- log: LogButtons() options for specifying depth and/or hiding depth slider
- filters: set a current filter that tree node can automatically query to hide themselves - filters: set a current filter that tree node can automatically query to hide themselves
- filters: handle wild-cards (with implicit leading/trailing *), reg-exprs - filters: handle wild-cards (with implicit leading/trailing *), reg-exprs
- filters: fuzzy matches (may use code at blog.forrestthewoods.com/4cffeed33fdb) - filters: fuzzy matches (may use code at blog.forrestthewoods.com/4cffeed33fdb)
- drag and drop: drag tooltip hovering over source widget with IsItemHovered/SetTooltip flickers.
- drag and drop: fix/support/options for overlapping drag sources.
- drag and drop: releasing a drop shows the "..." tooltip for one frame - since e13e598 (#1725) - drag and drop: releasing a drop shows the "..." tooltip for one frame - since e13e598 (#1725)
- drag and drop: drag source on a group object (would need e.g. an invisible button covering group in EndGroup) https://twitter.com/paniq/status/1121446364909535233
- drag and drop: have some way to know when a drag begin from BeginDragDropSource() pov. - drag and drop: have some way to know when a drag begin from BeginDragDropSource() pov.
- drag and drop: allow preview tooltip to be submitted from a different place than the drag source. (#1725) - drag and drop: allow preview tooltip to be submitted from a different place than the drag source. (#1725)
- drag and drop: allow using with other mouse buttons (where activeid won't be set). (#1637) - drag and drop: allow using with other mouse buttons (where activeid won't be set). (#1637)
- drag and drop: make it easier and provide a demo to have tooltip both are source and target site, with a more detailed one on target site (tooltip ordering problem) - drag and drop: make it easier and provide a demo to have tooltip both are source and target site, with a more detailed one on target site (tooltip ordering problem)
- drag and drop: test with reordering nodes (in a list, or a tree node). (#143) - drag and drop: demo with reordering nodes (in a list, or a tree node). (#143)
- drag and drop: test integrating with os drag and drop (make it easy to do a naive WM_DROPFILE integration) - drag and drop: test integrating with os drag and drop (make it easy to do a naive WM_DROPFILE integration)
- drag and drop: allow for multiple payload types. (#143)
- drag and drop: make payload optional? (#143) - drag and drop: make payload optional? (#143)
- drag and drop: feedback when hovering a modal (cursor?) - drag and drop: (#143) "both an in-process pointer and a promise to generate a serialized version, for whether the drag ends inside or outside the same process"
- drag and drop: feedback when hovering a region blocked by modal (mouse cursor "NO"?)
- node/graph editor (#306) - node/graph editor (#306)
- pie menus patterns (#434) - pie menus patterns (#434)
- markup: simple markup language for color change? (#902) - markup: simple markup language for color change? (#902)
@ -241,22 +273,24 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- font: a CalcTextHeight() helper could run faster than CalcTextSize().y - font: a CalcTextHeight() helper could run faster than CalcTextSize().y
- font: enforce monospace through ImFontConfig (for icons?) + create dual ImFont output from same input, reusing rasterized data but with different glyphs/AdvanceX - font: enforce monospace through ImFontConfig (for icons?) + create dual ImFont output from same input, reusing rasterized data but with different glyphs/AdvanceX
- font: finish CustomRectRegister() to allow mapping Unicode codepoint to custom texture data - font: finish CustomRectRegister() to allow mapping Unicode codepoint to custom texture data
- font: make it easier to submit own bitmap font (same texture, another texture?). (#2127, #2575)
- font: PushFontSize API (#1018) - font: PushFontSize API (#1018)
- font: MemoryTTF taking ownership confusing/not obvious, maybe default should be opposite? - font: MemoryTTF taking ownership confusing/not obvious, maybe default should be opposite?
- font: storing MinAdvanceX per font would allow us to skip calculating line width (under a threshold of character count) in loops looking for block width
- font/demo: add tools to show glyphs used by a text blob, display U16 value, list missing glyphs. - font/demo: add tools to show glyphs used by a text blob, display U16 value, list missing glyphs.
- font/demo: demonstrate use of ImFontGlyphRangesBuilder. - font/demo: demonstrate use of ImFontGlyphRangesBuilder.
- font/atlas: add a missing Glyphs.reserve() - font/atlas: add a missing Glyphs.reserve()
- font/atlas: incremental updates - font/atlas: incremental updates
- font/atlas: dynamic font atlas to avoid baking huge ranges into bitmap and make scaling easier. - font/atlas: dynamic font atlas to avoid baking huge ranges into bitmap and make scaling easier.
- font/atlas: allow user to submit its own primitive to be rectpacked, and allow to map them on a Unicode point.
- font/draw: vertical and/or rotated text renderer (#705) - vertical is easier clipping wise - font/draw: vertical and/or rotated text renderer (#705) - vertical is easier clipping wise
- font/draw: need to be able to specify wrap start position. - font/draw: need to be able to specify wrap start position.
- font/draw: better reserve policy for large horizontal block of text (shouldn't reserve for all clipped lines) - font/draw: better reserve policy for large horizontal block of text (shouldn't reserve for all clipped lines)
- font/draw: underline, squiggle line rendering helpers.
- font: optimization: for monospace font (like the default one) we can trim IndexXAdvance as long as trailing value is == FallbackXAdvance (need to make sure TAB is still correct), would save on cache line. - font: optimization: for monospace font (like the default one) we can trim IndexXAdvance as long as trailing value is == FallbackXAdvance (need to make sure TAB is still correct), would save on cache line.
- font: add support for kerning, probably optional. A) perhaps default to (32..128)^2 matrix ~ 9K entries = 36KB, then hash for non-ascii?. B) or sparse lookup into per-char list? - font: add support for kerning, probably optional. A) perhaps default to (32..128)^2 matrix ~ 9K entries = 36KB, then hash for non-ascii?. B) or sparse lookup into per-char list?
- font: add a simpler CalcTextSizeA() api? current one ok but not welcome if user needs to call it directly (without going through ImGui::CalcTextSize) - font: add a simpler CalcTextSizeA() api? current one ok but not welcome if user needs to call it directly (without going through ImGui::CalcTextSize)
- font: fix AddRemapChar() to work before font has been built. - font: fix AddRemapChar() to work before atlas has been built.
- font: what would it take to support codepoint higher than 0xFFFF? (smileys, etc.) - font: what would it take to support codepoint higher than 0xFFFF? (smileys, etc.) (#2538, #2541)
- font: (api breaking) remove "TTF" from symbol names. also because it now supports OTF. - font: (api breaking) remove "TTF" from symbol names. also because it now supports OTF.
- font/opt: Considering storing standalone AdvanceX table as 16-bit fixed point integer? - font/opt: Considering storing standalone AdvanceX table as 16-bit fixed point integer?
- font/opt: Glyph currently 40 bytes (2+9*4). Consider storing UV as 16 bits integer? (->32 bytes). X0/Y0/X1/Y1 as 16 fixed-point integers? Or X0/Y0 as float and X1/Y1 as fixed8_8? - font/opt: Glyph currently 40 bytes (2+9*4). Consider storing UV as 16 bits integer? (->32 bytes). X0/Y0/X1/Y1 as 16 fixed-point integers? Or X0/Y0 as float and X1/Y1 as fixed8_8?
@ -277,6 +311,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- nav/menus: allow pressing Menu to leave a sub-menu. - nav/menus: allow pressing Menu to leave a sub-menu.
- nav/menus: a way to access the main menu bar with Alt? (currently needs CTRL+TAB) - nav/menus: a way to access the main menu bar with Alt? (currently needs CTRL+TAB)
- nav/menus: when using the main menu bar, even though we restore focus after, the underlying window loses its title bar highlight during menu manipulation. could we prevent it? - nav/menus: when using the main menu bar, even though we restore focus after, the underlying window loses its title bar highlight during menu manipulation. could we prevent it?
- nav/menus: main menu bar currently cannot restore a NULL focus. Could save NavWindow at the time of being focused, similarly to what popup do?
- nav: simulate right-click or context activation? (SHIFT+F10) - nav: simulate right-click or context activation? (SHIFT+F10)
- nav: tabs should go through most/all widgets (in submission order?). - nav: tabs should go through most/all widgets (in submission order?).
- nav: when CTRL-Tab/windowing is active, the HoveredWindow detection doesn't take account of the window display re-ordering. - nav: when CTRL-Tab/windowing is active, the HoveredWindow detection doesn't take account of the window display re-ordering.
@ -293,21 +328,26 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- inputs: support track pad style scrolling & slider edit. - inputs: support track pad style scrolling & slider edit.
- inputs/io: backspace and arrows in the context of a text input could use system repeat rate. - inputs/io: backspace and arrows in the context of a text input could use system repeat rate.
- inputs/io: clarify/standardize/expose repeat rate and repeat delays (#1808) - inputs/io: clarify/standardize/expose repeat rate and repeat delays (#1808)
- inputs: add mouse cursor for unavailable/no? IDC_NO/SDL_SYSTEM_CURSOR_NO.
- inputs/scrolling: support for smooth scrolling (#2462, #2569)
- misc: idle: expose "woken up" boolean (set by inputs) and/or animation time (for cursor blink) for back-end to be able stop refreshing easily. - misc: idle: expose "woken up" boolean (set by inputs) and/or animation time (for cursor blink) for back-end to be able stop refreshing easily.
- misc: idle: if cursor blink if the _only_ visible animation, core imgui could rewrite vertex alpha to avoid CPU pass on ImGui:: calls. - misc: idle: if cursor blink if the _only_ visible animation, core imgui could rewrite vertex alpha to avoid CPU pass on ImGui:: calls.
- misc: idle: if cursor blink if the _only_ visible animation, could even expose a dirty rectangle that optionally can be leverage by some app to render in a smaller viewport, getting rid of much pixel shading cost.
- misc: make the ImGuiCond values linear (non-power-of-two). internal storage for ImGuiWindow can use integers to combine into flags (Why?) - misc: make the ImGuiCond values linear (non-power-of-two). internal storage for ImGuiWindow can use integers to combine into flags (Why?)
- misc: provide a way to compile out the entire implementation while providing a dummy API (e.g. #define IMGUI_DUMMY_IMPL) - misc: provide a way to compile out the entire implementation while providing a dummy API (e.g. #define IMGUI_DUMMY_IMPL)
- misc: PushItemFlag(): add a flag to disable keyboard capture when used with mouse? (#1682) - misc: PushItemFlag(): add a flag to disable keyboard capture when used with mouse? (#1682)
- misc: use more size_t in public api? - misc: use more size_t in public api?
- misc: possible compile-time support for string view/range instead of char* would e.g. facilitate usage with Rust (#683)
- misc: possible compile-time support for wchar_t instead of char*?
- backend: bgfx? https://gist.github.com/RichardGale/6e2b74bc42b3005e08397236e4be0fd0 - backend: bgfx? https://gist.github.com/RichardGale/6e2b74bc42b3005e08397236e4be0fd0
- web/emscriptem: refactor some examples to facilitate integration with emscripten main loop system. (#1713, #336) - emscriptem: with refactored examples, we could provide a direct imgui_impl_emscripten platform layer (see eg. https://github.com/floooh/sokol-samples/blob/master/html5/imgui-emsc.cc#L42)
- web/emscriptem: with refactored examples, we could provide a direct imgui_impl_emscripten platform layer (see eg. https://github.com/floooh/sokol-samples/blob/master/html5/imgui-emsc.cc#L42)
- remote: make a system like RemoteImGui first-class citizen/project (#75) - remote: make a system like RemoteImGui first-class citizen/project (#75)
- demo: find a way to demonstrate textures in the examples application, as it such a a common issue for new users. - demo: find a way to demonstrate textures in the examples application, as it such a common issue for new users.
- demo: demonstrate using PushStyleVar() in more details.
- demo: add vertical separator demo - demo: add vertical separator demo
- demo: add virtual scrolling example? - demo: add virtual scrolling example?
- demo: demonstrate Plot offset - demo: demonstrate Plot offset
@ -315,6 +355,10 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- examples: provide a zero frame-rate/idle example. - examples: provide a zero frame-rate/idle example.
- examples: apple: example_apple should be using modern GL3. - examples: apple: example_apple should be using modern GL3.
- examples: glfw: could go idle when minimized? if (glfwGetWindowAttrib(window, GLFW_ICONIFIED)) { glfwWaitEvents(); continue; } // issue: DeltaTime will be super high on resume, perhaps provide a way to let impl know (#440) - examples: glfw: could go idle when minimized? if (glfwGetWindowAttrib(window, GLFW_ICONIFIED)) { glfwWaitEvents(); continue; } // issue: DeltaTime will be super high on resume, perhaps provide a way to let impl know (#440)
- examples: opengl: rename imgui_impl_opengl2 to impl_opengl_legacy and imgui_impl_opengl3 to imgui_impl_opengl? (#1900)
- examples: opengl: could use a single vertex buffer and glBufferSubData for uploads?
- examples: opengl: explicitly disable GL_STENCIL_TEST in bindings.
- examples: vulkan: viewport: support for synchronized swapping of multiple swap chains.
- optimization: replace vsnprintf with stb_printf? or enable the defines/infrastructure to allow it (#1038) - optimization: replace vsnprintf with stb_printf? or enable the defines/infrastructure to allow it (#1038)
- optimization: add clipping for multi-component widgets (SliderFloatX, ColorEditX, etc.). one problem is that nav branch can't easily clip parent group when there is a move request. - optimization: add clipping for multi-component widgets (SliderFloatX, ColorEditX, etc.). one problem is that nav branch can't easily clip parent group when there is a move request.
- optimization: add a flag to disable most of rendering, for the case where the user expect to skip it (#335) - optimization: add a flag to disable most of rendering, for the case where the user expect to skip it (#335)

View File

@ -3,12 +3,16 @@
1. PLEASE CAREFULLY READ: 1. PLEASE CAREFULLY READ:
https://github.com/ocornut/imgui/issues/2261 https://github.com/ocornut/imgui/issues/2261
2. IF YOU ARE HAVING AN ISSUE COMPILING/LINKING/RUNNING/DISPLAYING/ADDING FONTS, please post on the "Getting Started" Discourse forum: 2. IF YOU ARE HAVING AN ISSUE COMPILING/LINKING/RUNNING/LOADING FONTS, please post on the "Getting Started" Discourse forum:
https://discourse.dearimgui.org/c/getting-started https://discourse.dearimgui.org
3. PLEASE MAKE SURE that you have: read the FAQ in imgui.cpp; explored the contents of ShowDemoWindow() including the Examples menu; searched among Issues; used your IDE to search for keywords in all sources and text files; and read the link provided in (1). 3. PLEASE MAKE SURE that you have: read the FAQ in imgui.cpp; explored the contents of `ShowDemoWindow()` including the Examples menu; searched among Issues; used your IDE to search for keywords in all sources and text files; and read the link provided in (1).
4. Delete points 1-4 and PLEASE FILL THE TEMPLATE BELOW before submitting your issue. 4. Be mindful that messages are being sent to the e-mail box of "Watching" users. Try to proof-read your messages before sending them. Edits are not seen by those users.
5. Delete points 1-5 and PLEASE FILL THE TEMPLATE BELOW before submitting your issue.
Thank you!
---- ----

4
examples/.gitignore vendored
View File

@ -25,12 +25,16 @@ project.xcworkspace
xcuserdata xcuserdata
## Emscripten output ## Emscripten output
*.o.tmp
*.out.js *.out.js
*.out.wasm *.out.wasm
example_emscripten/example_emscripten.*
## Unix executables ## Unix executables
example_glfw_opengl2/example_glfw_opengl2 example_glfw_opengl2/example_glfw_opengl2
example_glfw_opengl3/example_glfw_opengl3 example_glfw_opengl3/example_glfw_opengl3
example_glut_opengl2/example_glut_opengl2
example_null/example_null
example_sdl_opengl2/example_sdl_opengl2 example_sdl_opengl2/example_sdl_opengl2
example_sdl_opengl3/example_sdl_opengl3 example_sdl_opengl3/example_sdl_opengl3

View File

@ -1,3 +1,5 @@
-----------------------------------------------------------------------
dear imgui, v1.71
----------------------------------------------------------------------- -----------------------------------------------------------------------
examples/README.txt examples/README.txt
(This is the README file for the examples/ folder. See docs/ for more documentation) (This is the README file for the examples/ folder. See docs/ for more documentation)
@ -26,7 +28,7 @@ This folder contains two things:
They are the in the XXXX_example/ sub-folders. They are the in the XXXX_example/ sub-folders.
You can find binaries of some of those example applications at: You can find binaries of some of those example applications at:
http://www.miracleworld.net/imgui/binaries http://www.dearimgui.org/binaries
--------------------------------------- ---------------------------------------
@ -89,9 +91,9 @@ Most the example bindings are split in 2 parts:
This is counter-intuitive, but this will get you running faster! Once you better understand how imgui This is counter-intuitive, but this will get you running faster! Once you better understand how imgui
works and is bound, you can rewrite the code using your own systems. works and is bound, you can rewrite the code using your own systems.
- Road-map: Dear ImGui 1.70 (WIP currently in the "viewport" branch) will allows imgui windows to be - Road-map: Dear ImGui 1.80 (WIP currently in the "docking" branch) will allows imgui windows to be
seamlessly detached from the main application window. This is achieved using an extra layer to the seamlessly detached from the main application window. This is achieved using an extra layer to the
platform and renderer bindings, which allows imgui to communicate platform-specific requests. platform and renderer bindings, which allows Dear ImGui to communicate platform-specific requests.
If you decide to use unmodified imgui_impl_xxxx.cpp files, you will automatically benefit from If you decide to use unmodified imgui_impl_xxxx.cpp files, you will automatically benefit from
improvements and fixes related to viewports and platform windows without extra work on your side. improvements and fixes related to viewports and platform windows without extra work on your side.
@ -99,10 +101,10 @@ Most the example bindings are split in 2 parts:
List of Platforms Bindings in this repository: List of Platforms Bindings in this repository:
imgui_impl_glfw.cpp ; GLFW (Windows, macOS, Linux, etc.) http://www.glfw.org/ imgui_impl_glfw.cpp ; GLFW (Windows, macOS, Linux, etc.) http://www.glfw.org/
imgui_impl_osx.mm ; macOS native API imgui_impl_osx.mm ; macOS native API (not as feature complete as glfw/sdl back-ends)
imgui_impl_sdl.cpp ; SDL2 (Windows, macOS, Linux, iOS, Android) https://www.libsdl.org imgui_impl_sdl.cpp ; SDL2 (Windows, macOS, Linux, iOS, Android) https://www.libsdl.org
imgui_impl_win32.cpp ; Win32 native API (Windows) imgui_impl_win32.cpp ; Win32 native API (Windows)
imgui_impl_freeglut.cpp ; FreeGLUT (if you really miss the 90's) imgui_impl_glut.cpp ; GLUT/FreeGLUT (absolutely not recommended in 2019)
List of Renderer Bindings in this repository: List of Renderer Bindings in this repository:
@ -112,7 +114,7 @@ List of Renderer Bindings in this repository:
imgui_impl_dx12.cpp ; DirectX12 imgui_impl_dx12.cpp ; DirectX12
imgui_impl_metal.mm ; Metal (with ObjC) imgui_impl_metal.mm ; Metal (with ObjC)
imgui_impl_opengl2.cpp ; OpenGL 2 (legacy, fixed pipeline <- don't use with modern OpenGL context) imgui_impl_opengl2.cpp ; OpenGL 2 (legacy, fixed pipeline <- don't use with modern OpenGL context)
imgui_impl_opengl3.cpp ; OpenGL3, OpenGL ES 2, OpenGL ES 3 (modern programmable pipeline) imgui_impl_opengl3.cpp ; OpenGL 3/4, OpenGL ES 2, OpenGL ES 3 (modern programmable pipeline)
imgui_impl_vulkan.cpp ; Vulkan imgui_impl_vulkan.cpp ; Vulkan
List of high-level Frameworks Bindings in this repository: (combine Platform + Renderer) List of high-level Frameworks Bindings in this repository: (combine Platform + Renderer)
@ -120,13 +122,15 @@ List of high-level Frameworks Bindings in this repository: (combine Platform + R
imgui_impl_allegro5.cpp imgui_impl_allegro5.cpp
imgui_impl_marmalade.cpp imgui_impl_marmalade.cpp
Note that Dear ImGui works with Emscripten.
The examples_emscripten/ app uses sdl.cpp + opengl3.cpp but other combinations are possible.
Third-party framework, graphics API and languages bindings are listed at: Third-party framework, graphics API and languages bindings are listed at:
https://github.com/ocornut/imgui/wiki/Bindings https://github.com/ocornut/imgui/wiki/Bindings
Languages: C, C#, ChaiScript, D, Go, Haxe, Java, Lua, Odin, Pascal, PureBasic, Python, Rust, Swift... Languages: C, C#, ChaiScript, D, Go, Haxe, Java, Lua, Odin, Pascal, PureBasic, Python, Rust, Swift...
Frameworks: Cinder, Cocoa (OSX), Cocos2d-x, Emscripten, SFML, GML/GameMaker Studio, Irrlicht, Ogre, Frameworks: Cinder, Cocoa (OSX), Cocos2d-x, SFML, GML/GameMaker Studio, Irrlicht, Ogre, OpenSceneGraph,
OpenSceneGraph, openFrameworks, LOVE, NanoRT, Nim Game Lib, Qt3d, SFML, Unreal Engine 4... openFrameworks, LOVE, NanoRT, Nim Game Lib, Qt3d, SFML, Unreal Engine 4...
Miscellaneous: Software Renderer, RemoteImgui, etc. Miscellaneous: Software Renderer, RemoteImgui, etc.
@ -147,6 +151,96 @@ Building:
directly with a command-line compiler. directly with a command-line compiler.
example_allegro5/
Allegro 5 example.
= main.cpp + imgui_impl_allegro5.cpp
example_apple_metal/
OSX & iOS + Metal.
= main.m + imgui_impl_osx.mm + imgui_impl_metal.mm
It is based on the "cross-platform" game template provided with Xcode as of Xcode 9.
(NB: imgui_impl_osx.mm is currently not as feature complete as other platforms back-ends.
You may prefer to use the GLFW Or SDL back-ends, which will also support Windows and Linux.)
example_apple_opengl2/
OSX + OpenGL2.
= main.mm + imgui_impl_osx.mm + imgui_impl_opengl2.cpp
(NB: imgui_impl_osx.mm is currently not as feature complete as other platforms back-ends.
You may prefer to use the GLFW Or SDL back-ends, which will also support Windows and Linux.)
example_empscripten:
Emcripten + SDL2 + OpenGL3+/ES2/ES3 example.
= main.cpp + imgui_impl_sdl.cpp + imgui_impl_opengl3.cpp
Note that other examples based on SDL or GLFW + OpenGL could easily be modified to work with Emscripten.
We provide this to make the Emscripten differences obvious, and have them not pollute all other examples.
example_glfw_metal/
GLFW (Mac) + Metal example.
= main.mm + imgui_impl_glfw.cpp + imgui_impl_metal.mm.
example_glfw_opengl2/
GLFW + OpenGL2 example (legacy, fixed pipeline).
= main.cpp + imgui_impl_glfw.cpp + imgui_impl_opengl2.cpp
**DO NOT USE OPENGL2 CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)**
**Prefer using OPENGL3 code (with gl3w/glew/glad, you can replace the OpenGL function loader)**
This code is mostly provided as a reference to learn about Dear ImGui integration, because it is shorter.
If your code is using GL3+ context or any semi modern OpenGL calls, using this renderer is likely to
make things more complicated, will require your code to reset many OpenGL attributes to their initial
state, and might confuse your GPU driver. One star, not recommended.
example_glfw_opengl3/
GLFW (Win32, Mac, Linux) + OpenGL3+/ES2/ES3 example (programmable pipeline).
= main.cpp + imgui_impl_glfw.cpp + imgui_impl_opengl3.cpp
This uses more modern OpenGL calls and custom shaders.
Prefer using that if you are using modern OpenGL in your application (anything with shaders).
(Please be mindful that accessing OpenGL3+ functions requires a function loader, which are a frequent
source for confusion for new users. We use a loader in imgui_impl_opengl3.cpp which may be different
from the one your app normally use. Read imgui_impl_opengl3.h for details and how to change it.)
example_glfw_vulkan/
GLFW (Win32, Mac, Linux) + Vulkan example.
= main.cpp + imgui_impl_glfw.cpp + imgui_impl_vulkan.cpp
This is quite long and tedious, because: Vulkan.
example_glut_opengl2/
GLUT (e.g., FreeGLUT on Linux/Windows, GLUT framework on OSX) + OpenGL2.
= main.cpp + imgui_impl_glut.cpp + imgui_impl_opengl2.cpp
Note that GLUT/FreeGLUT is largely obsolete software, prefer using GLFW or SDL.
example_marmalade/
Marmalade example using IwGx.
= main.cpp + imgui_impl_marmalade.cpp
example_null
Null example, compile and link imgui, create context, run headless with no inputs and no graphics output.
= main.cpp
This is used to quickly test compilation of core imgui files in as many setups as possible.
Because this application doesn't create a window nor a graphic context, there's no graphics output.
example_sdl_opengl2/
SDL2 (Win32, Mac, Linux etc.) + OpenGL example (legacy, fixed pipeline).
= main.cpp + imgui_impl_sdl.cpp + imgui_impl_opengl2.cpp
**DO NOT USE OPENGL2 CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)**
**Prefer using OPENGL3 code (with gl3w/glew/glad, you can replace the OpenGL function loader)**
This code is mostly provided as a reference to learn about Dear ImGui integration, because it is shorter.
If your code is using GL3+ context or any semi modern OpenGL calls, using this renderer is likely to
make things more complicated, will require your code to reset many OpenGL attributes to their initial
state, and might confuse your GPU driver. One star, not recommended.
example_sdl_opengl3/
SDL2 (Win32, Mac, Linux, etc.) + OpenGL3+/ES2/ES3 example.
= main.cpp + imgui_impl_sdl.cpp + imgui_impl_opengl3.cpp
This uses more modern OpenGL calls and custom shaders.
Prefer using that if you are using modern OpenGL in your application (anything with shaders).
(Please be mindful that accessing OpenGL3+ functions requires a function loader, which are a frequent
source for confusion for new users. We use a loader in imgui_impl_opengl3.cpp which may be different
from the one your app normally use. Read imgui_impl_opengl3.h for details and how to change it.)
example_sdl_vulkan/
SDL2 (Win32, Mac, Linux, etc.) + Vulkan example.
= main.cpp + imgui_impl_sdl.cpp + imgui_impl_vulkan.cpp
This is quite long and tedious, because: Vulkan.
example_win32_directx9/ example_win32_directx9/
DirectX9 example, Windows only. DirectX9 example, Windows only.
= main.cpp + imgui_impl_win32.cpp + imgui_impl_dx9.cpp = main.cpp + imgui_impl_win32.cpp + imgui_impl_dx9.cpp
@ -161,70 +255,5 @@ example_win32_directx11/
example_win32_directx12/ example_win32_directx12/
DirectX12 example, Windows only. DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
= main.cpp + imgui_impl_win32.cpp + imgui_impl_dx12.cpp = main.cpp + imgui_impl_win32.cpp + imgui_impl_dx12.cpp
This is quite long and tedious, because: DirectX12.
example_apple_metal/
OSX & iOS + Metal.
It is based on the "cross-platform" game template provided with Xcode as of Xcode 9.
(NB: you may still want to use GLFW or SDL which will also support Windows, Linux along with OSX.)
= game template + imgui_impl_osx.mm + imgui_impl_metal.mm
example_apple_opengl2/
OSX + OpenGL2.
(NB: you may still want to use GLFW or SDL which will also support Windows, Linux along with OSX.)
= main.mm + imgui_impl_osx.mm + imgui_impl_opengl2.cpp
example_glfw_opengl2/
**DO NOT USE OPENGL2 CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)**
**Prefer using OPENGL3 code (with gl3w/glew/glad, you can replace the OpenGL function loader)**
GLFW + OpenGL2 example (legacy, fixed pipeline).
This code is mostly provided as a reference to learn about Dear ImGui integration, because it is shorter.
If your code is using GL3+ context or any semi modern OpenGL calls, using this renderer is likely to
make things more complicated, will require your code to reset many OpenGL attributes to their initial
state, and might confuse your GPU driver. One star, not recommended.
= main.cpp + imgui_impl_glfw.cpp + imgui_impl_opengl2.cpp
example_glfw_opengl3/
GLFW (Win32, Mac, Linux) + OpenGL3+/ES2/ES3 example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders.
Prefer using that if you are using modern OpenGL in your application (anything with shaders).
= main.cpp + imgui_impl_glfw.cpp + imgui_impl_opengl3.cpp
example_glfw_vulkan/
GLFW (Win32, Mac, Linux) + Vulkan example.
This is quite long and tedious, because: Vulkan.
= main.cpp + imgui_impl_glfw.cpp + imgui_impl_vulkan.cpp
example_sdl_opengl2/
**DO NOT USE OPENGL2 CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)**
**Prefer using OPENGL3 code (with gl3w/glew/glad, you can replace the OpenGL function loader)**
SDL2 (Win32, Mac, Linux etc.) + OpenGL example (legacy, fixed pipeline).
This code is mostly provided as a reference to learn about Dear ImGui integration, because it is shorter.
If your code is using GL3+ context or any semi modern OpenGL calls, using this renderer is likely to
make things more complicated, will require your code to reset many OpenGL attributes to their initial
state, and might confuse your GPU driver. One star, not recommended.
= main.cpp + imgui_impl_sdl.cpp + imgui_impl_opengl2.cpp
example_sdl_opengl3/
SDL2 (Win32, Mac, Linux, etc.) + OpenGL3+/ES2/ES3 example.
This uses more modern OpenGL calls and custom shaders.
Prefer using that if you are using modern OpenGL in your application (anything with shaders).
= main.cpp + imgui_impl_sdl.cpp + imgui_impl_opengl3.cpp
example_sdl_vulkan/
SDL2 (Win32, Mac, Linux, etc.) + Vulkan example.
This is quite long and tedious, because: Vulkan.
= main.cpp + imgui_impl_sdl.cpp + imgui_impl_vulkan.cpp
example_allegro5/
Allegro 5 example.
= main.cpp + imgui_impl_allegro5.cpp
example_freeglut_opengl2/
FreeGLUT + OpenGL2.
= main.cpp + imgui_impl_freeglut.cpp + imgui_impl_opengl2.cpp
example_marmalade/
Marmalade example using IwGx.
= main.cpp + imgui_impl_marmalade.cpp

View File

@ -2,21 +2,31 @@
# Configuration # Configuration
Dear ImGui outputs 16-bit vertex indices by default. Dear ImGui outputs 16-bit vertex indices by default.
Allegro doesn't support them natively, so we have two solutions: convert the indices manually in imgui_impl_allegro5.cpp, or compile imgui with 32-bit indices. Allegro doesn't support them natively, so we have two solutions: convert the indices manually in imgui_impl_allegro5.cpp, or compile dear imgui with 32-bit indices.
You can either modify imconfig.h that comes with Dear ImGui (easier), or set a C++ preprocessor option IMGUI_USER_CONFIG to find to a filename. You can either modify imconfig.h that comes with Dear ImGui (easier), or set a C++ preprocessor option IMGUI_USER_CONFIG to find to a filename.
We are providing `imconfig_allegro5.h` that enables 32-bit indices. We are providing `imconfig_allegro5.h` that enables 32-bit indices.
Note that the back-end supports _BOTH_ 16-bit and 32-bit indices, but 32-bit indices will be slightly faster as they won't require a manual conversion. Note that the back-end supports _BOTH_ 16-bit and 32-bit indices, but 32-bit indices will be slightly faster as they won't require a manual conversion.
# How to Build # How to Build
- On Ubuntu 14.04+ ### On Ubuntu 14.04+
```bash ```bash
g++ -DIMGUI_USER_CONFIG=\"examples/example_allegro5/imconfig_allegro5.h\" -I .. -I ../.. main.cpp ..\imgui_impl_allegro5.cpp ../../imgui*.cpp -lallegro -lallegro_primitives -o allegro5_example g++ -DIMGUI_USER_CONFIG=\"examples/example_allegro5/imconfig_allegro5.h\" -I .. -I ../.. main.cpp ../imgui_impl_allegro5.cpp ../../imgui*.cpp -lallegro -lallegro_primitives -o allegro5_example
``` ```
- On Windows with Visual Studio's CLI ### On Windows with Visual Studio's CLI
You may install Allegro using vcpkg:
```
git clone https://github.com/Microsoft/vcpkg
cd vcpkg
.\bootstrap-vcpkg.bat
.\vcpkg install allegro5
.\vcpkg integrate install ; optional, automatically register include/libs in Visual Studio
```
Build:
``` ```
set ALLEGRODIR=path_to_your_allegro5_folder set ALLEGRODIR=path_to_your_allegro5_folder
cl /Zi /MD /I %ALLEGRODIR%\include /DIMGUI_USER_CONFIG=\"examples/example_allegro5/imconfig_allegro5.h\" /I .. /I ..\.. main.cpp ..\imgui_impl_allegro5.cpp ..\..\imgui*.cpp /link /LIBPATH:%ALLEGRODIR%\lib allegro-5.0.10-monolith-md.lib user32.lib cl /Zi /MD /I %ALLEGRODIR%\include /DIMGUI_USER_CONFIG=\"examples/example_allegro5/imconfig_allegro5.h\" /I .. /I ..\.. main.cpp ..\imgui_impl_allegro5.cpp ..\..\imgui*.cpp /link /LIBPATH:%ALLEGRODIR%\lib allegro-5.0.10-monolith-md.lib user32.lib

View File

@ -21,29 +21,34 @@
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741}</ProjectGuid> <ProjectGuid>{2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741}</ProjectGuid>
<RootNamespace>example_allegro5</RootNamespace> <RootNamespace>example_allegro5</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">

View File

@ -1,4 +1,3 @@
#import <TargetConditionals.h> #import <TargetConditionals.h>
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE

View File

@ -1,4 +1,3 @@
#import "AppDelegate.h" #import "AppDelegate.h"
@implementation AppDelegate @implementation AppDelegate

View File

@ -1,4 +1,3 @@
#import <MetalKit/MetalKit.h> #import <MetalKit/MetalKit.h>
@interface Renderer : NSObject <MTKViewDelegate> @interface Renderer : NSObject <MTKViewDelegate>

View File

@ -1,4 +1,3 @@
#import "Renderer.h" #import "Renderer.h"
#import <Metal/Metal.h> #import <Metal/Metal.h>

View File

@ -1,4 +1,3 @@
#import <Metal/Metal.h> #import <Metal/Metal.h>
#import <MetalKit/MetalKit.h> #import <MetalKit/MetalKit.h>
#import "Renderer.h" #import "Renderer.h"

View File

@ -1,4 +1,3 @@
#import "ViewController.h" #import "ViewController.h"
#import "Renderer.h" #import "Renderer.h"
#include "imgui.h" #include "imgui.h"

View File

@ -1,4 +1,3 @@
#import <TargetConditionals.h> #import <TargetConditionals.h>
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE

View File

@ -38,14 +38,11 @@
4080A99F20B034280036BA46 /* imgui_impl_osx.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = imgui_impl_osx.mm; path = ../imgui_impl_osx.mm; sourceTree = "<group>"; }; 4080A99F20B034280036BA46 /* imgui_impl_osx.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = imgui_impl_osx.mm; path = ../imgui_impl_osx.mm; sourceTree = "<group>"; };
4080A9A020B034280036BA46 /* imgui_impl_opengl2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_impl_opengl2.h; path = ../imgui_impl_opengl2.h; sourceTree = "<group>"; }; 4080A9A020B034280036BA46 /* imgui_impl_opengl2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_impl_opengl2.h; path = ../imgui_impl_opengl2.h; sourceTree = "<group>"; };
4080A9A120B034280036BA46 /* imgui_impl_osx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_impl_osx.h; path = ../imgui_impl_osx.h; sourceTree = "<group>"; }; 4080A9A120B034280036BA46 /* imgui_impl_osx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_impl_osx.h; path = ../imgui_impl_osx.h; sourceTree = "<group>"; };
4080A9A420B0343C0036BA46 /* stb_truetype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stb_truetype.h; path = ../../stb_truetype.h; sourceTree = "<group>"; };
4080A9A520B0343C0036BA46 /* imgui_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_internal.h; path = ../../imgui_internal.h; sourceTree = "<group>"; }; 4080A9A520B0343C0036BA46 /* imgui_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_internal.h; path = ../../imgui_internal.h; sourceTree = "<group>"; };
4080A9A620B0343C0036BA46 /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../imgui_demo.cpp; sourceTree = "<group>"; }; 4080A9A620B0343C0036BA46 /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../imgui_demo.cpp; sourceTree = "<group>"; };
4080A9A720B0343C0036BA46 /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = "<group>"; }; 4080A9A720B0343C0036BA46 /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = "<group>"; };
4080A9A820B0343C0036BA46 /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = "<group>"; }; 4080A9A820B0343C0036BA46 /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = "<group>"; };
4080A9A920B0343C0036BA46 /* stb_rect_pack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stb_rect_pack.h; path = ../../stb_rect_pack.h; sourceTree = "<group>"; };
4080A9AA20B0343C0036BA46 /* imgui_draw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_draw.cpp; path = ../../imgui_draw.cpp; sourceTree = "<group>"; }; 4080A9AA20B0343C0036BA46 /* imgui_draw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_draw.cpp; path = ../../imgui_draw.cpp; sourceTree = "<group>"; };
4080A9AB20B0343C0036BA46 /* stb_textedit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stb_textedit.h; path = ../../stb_textedit.h; sourceTree = "<group>"; };
4080A9AC20B0343C0036BA46 /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = "<group>"; }; 4080A9AC20B0343C0036BA46 /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = "<group>"; };
4080A9B220B034E40036BA46 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 4080A9B220B034E40036BA46 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
4080A9B420B034EA0036BA46 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; 4080A9B420B034EA0036BA46 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
@ -74,9 +71,6 @@
4080A9A620B0343C0036BA46 /* imgui_demo.cpp */, 4080A9A620B0343C0036BA46 /* imgui_demo.cpp */,
4080A9AA20B0343C0036BA46 /* imgui_draw.cpp */, 4080A9AA20B0343C0036BA46 /* imgui_draw.cpp */,
4080A9A520B0343C0036BA46 /* imgui_internal.h */, 4080A9A520B0343C0036BA46 /* imgui_internal.h */,
4080A9A920B0343C0036BA46 /* stb_rect_pack.h */,
4080A9AB20B0343C0036BA46 /* stb_textedit.h */,
4080A9A420B0343C0036BA46 /* stb_truetype.h */,
4080A99E20B034280036BA46 /* imgui_impl_opengl2.cpp */, 4080A99E20B034280036BA46 /* imgui_impl_opengl2.cpp */,
4080A9A020B034280036BA46 /* imgui_impl_opengl2.h */, 4080A9A020B034280036BA46 /* imgui_impl_opengl2.h */,
4080A9A120B034280036BA46 /* imgui_impl_osx.h */, 4080A9A120B034280036BA46 /* imgui_impl_osx.h */,

View File

@ -91,14 +91,14 @@
ImGui::Render(); ImGui::Render();
[[self openGLContext] makeCurrentContext]; [[self openGLContext] makeCurrentContext];
ImGuiIO& io = ImGui::GetIO(); ImDrawData* draw_data = ImGui::GetDrawData();
GLsizei width = (GLsizei)(io.DisplaySize.x * io.DisplayFramebufferScale.x); GLsizei width = (GLsizei)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
GLsizei height = (GLsizei)(io.DisplaySize.y * io.DisplayFramebufferScale.y); GLsizei height = (GLsizei)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
glViewport(0, 0, width, height); glViewport(0, 0, width, height);
glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData()); ImGui_ImplOpenGL2_RenderDrawData(draw_data);
// Present // Present
[[self openGLContext] flushBuffer]; [[self openGLContext] flushBuffer];

View File

@ -0,0 +1,60 @@
#
# Makefile to use with emscripten
# See https://emscripten.org/docs/getting_started/downloads.html
# for installation instructions. This Makefile assumes you have
# loaded emscripten's environment.
#
# Running `make` will produce three files:
# - example_emscripten.html
# - example_emscripten.js
# - example_emscripten.wasm
#
# All three are needed to run the demo.
CC = emcc
CXX = em++
EXE = example_emscripten.html
SOURCES = main.cpp
SOURCES += ../imgui_impl_sdl.cpp ../imgui_impl_opengl3.cpp
SOURCES += ../../imgui.cpp ../../imgui_demo.cpp ../../imgui_draw.cpp ../../imgui_widgets.cpp
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
UNAME_S := $(shell uname -s)
EMS = -s USE_SDL=2 -s WASM=1
EMS += -s ALLOW_MEMORY_GROWTH=1 -s BINARYEN_TRAP_MODE=clamp
EMS += -s DISABLE_EXCEPTION_CATCHING=1 -s NO_EXIT_RUNTIME=0
EMS += -s ASSERTIONS=1 -s NO_FILESYSTEM=1
#EMS += -s SAFE_HEAP=1 ## Adds overhead
CPPFLAGS = -I../ -I../../
#CPPFLAGS += -g
CPPFLAGS += -Wall -Wformat -Os
CPPFLAGS += $(EMS)
LIBS = $(EMS)
LDFLAGS = --shell-file shell_minimal.html
##---------------------------------------------------------------------
## BUILD RULES
##---------------------------------------------------------------------
%.o:%.cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<
%.o:../%.cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<
%.o:../../%.cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<
%.o:../libs/gl3w/GL/%.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
all: $(EXE)
@echo Build complete for $(EXE)
$(EXE): $(OBJS)
$(CXX) -o $@ $^ $(LIBS) $(LDFLAGS)
clean:
rm -f $(EXE) $(OBJS) *.js *.wasm *.wasm.pre

View File

@ -0,0 +1,8 @@
# How to Build
- You need to install Emscripten from https://emscripten.org/docs/getting_started/downloads.html, and have the environment variables set, as described in https://emscripten.org/docs/getting_started/downloads.html#installation-instructions
```
em++ -I.. -I../.. main.cpp ../imgui_impl_sdl.cpp ../imgui_impl_opengl3.cpp ../../imgui*.cpp -s USE_SDL=2 -s USE_WEBGL2=1 -s WASM=1 -s FULL_ES3=1 -s ALLOW_MEMORY_GROWTH=1 -s BINARYEN_TRAP_MODE=clamp --shell-file shell_minimal.html -o example-emscripten.html
```

View File

@ -0,0 +1,170 @@
// dear imgui: standalone example application for Emscripten, using SDL2 + OpenGL3
// This is mostly the same code as the SDL2 + OpenGL3 example, simply with the modifications needed to run on Emscripten.
// It is possible to combine both code into a single source file that will compile properly on Desktop and using Emscripten.
// See https://github.com/ocornut/imgui/pull/2492 as an example on how to do just that.
//
// If you are new to dear imgui, see examples/README.txt and documentation at the top of imgui.cpp.
// (Emscripten is a C++-to-javascript compiler, used to publish executables for the web. See https://emscripten.org/)
#include "imgui.h"
#include "imgui_impl_sdl.h"
#include "imgui_impl_opengl3.h"
#include <stdio.h>
#include <emscripten.h>
#include <SDL.h>
#include <SDL_opengles2.h>
// Emscripten requires to have full control over the main loop. We're going to store our SDL book-keeping variables globally.
// Having a single function that acts as a loop prevents us to store state in the stack of said function. So we need some location for this.
SDL_Window* g_Window = NULL;
SDL_GLContext g_GLContext = NULL;
// For clarity, our main loop code is declared at the end.
void main_loop(void*);
int main(int, char**)
{
// Setup SDL
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
{
printf("Error: %s\n", SDL_GetError());
return -1;
}
// For the browser using Emscripten, we are going to use WebGL1 with GL ES2. See the Makefile. for requirement details.
// It is very likely the generated file won't work in many browsers. Firefox is the only sure bet, but I have successfully
// run this code on Chrome for Android for example.
const char* glsl_version = "#version 100";
//const char* glsl_version = "#version 300 es";
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
// Create window with graphics context
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
SDL_DisplayMode current;
SDL_GetCurrentDisplayMode(0, &current);
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
g_Window = SDL_CreateWindow("Dear ImGui Emscripten example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
g_GLContext = SDL_GL_CreateContext(g_Window);
if (!g_GLContext)
{
fprintf(stderr, "Failed to initialize WebGL context!\n");
return 1;
}
SDL_GL_SetSwapInterval(1); // Enable vsync
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
// For an Emscripten build we are disabling file-system access, so let's not attempt to do a fopen() of the imgui.ini file.
// You may manually call LoadIniSettingsFromMemory() to load settings from your own storage.
io.IniFilename = NULL;
// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Setup Platform/Renderer bindings
ImGui_ImplSDL2_InitForOpenGL(g_Window, g_GLContext);
ImGui_ImplOpenGL3_Init(glsl_version);
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
// - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
// - Read 'misc/fonts/README.txt' for more instructions and details.
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
//io.Fonts->AddFontDefault();
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f);
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese());
//IM_ASSERT(font != NULL);
// This function call won't return, and will engage in an infinite loop, processing events from the browser, and dispatching them.
emscripten_set_main_loop_arg(main_loop, NULL, 0, true);
}
void main_loop(void* arg)
{
ImGuiIO& io = ImGui::GetIO();
IM_UNUSED(arg); // We can pass this argument as the second parameter of emscripten_set_main_loop_arg(), but we don't use that.
// Our state (make them static = more or less global) as a convenience to keep the example terse.
static bool show_demo_window = true;
static bool show_another_window = false;
static ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
// Poll and handle events (inputs, window resize, etc.)
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
SDL_Event event;
while (SDL_PollEvent(&event))
{
ImGui_ImplSDL2_ProcessEvent(&event);
// Capture events here, based on io.WantCaptureMouse and io.WantCaptureKeyboard
}
// Start the Dear ImGui frame
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplSDL2_NewFrame(g_Window);
ImGui::NewFrame();
// 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!).
if (show_demo_window)
ImGui::ShowDemoWindow(&show_demo_window);
// 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window.
{
static float f = 0.0f;
static int counter = 0;
ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it.
ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too)
ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state
ImGui::Checkbox("Another Window", &show_another_window);
ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated)
counter++;
ImGui::SameLine();
ImGui::Text("counter = %d", counter);
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
ImGui::End();
}
// 3. Show another simple window.
if (show_another_window)
{
ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
ImGui::Text("Hello from another window!");
if (ImGui::Button("Close Me"))
show_another_window = false;
ImGui::End();
}
// Rendering
ImGui::Render();
SDL_GL_MakeCurrent(g_Window, g_GLContext);
glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
glClear(GL_COLOR_BUFFER_BIT);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
SDL_GL_SwapWindow(g_Window);
}

View File

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

View File

@ -0,0 +1,44 @@
#
# You will need GLFW (http://www.glfw.org):
# brew install glfw
#
#CXX = g++
#CXX = clang++
EXE = example_glfw_metal
SOURCES = main.mm
SOURCES += ../imgui_impl_glfw.cpp ../imgui_impl_metal.mm
SOURCES += ../../imgui.cpp ../../imgui_widgets.cpp ../../imgui_demo.cpp ../../imgui_draw.cpp
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
LIBS = -framework Metal -framework MetalKit -framework Cocoa -framework IOKit -framework CoreVideo -framework QuartzCore
LIBS += -L/usr/local/lib -lglfw
CXXFLAGS = -I../ -I../../ -I/usr/local/include
CXXFLAGS += -Wall -Wformat
CFLAGS = $(CXXFLAGS)
%.o:%.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
%.o:../%.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
%.o:../../%.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
%.o:../%.mm
$(CXX) $(CXXFLAGS) -ObjC++ -fobjc-weak -fobjc-arc -c -o $@ $<
%.o:%.mm
$(CXX) $(CXXFLAGS) -ObjC++ -fobjc-weak -fobjc-arc -c -o $@ $<
all: $(EXE)
@echo Build complete
$(EXE): $(OBJS)
$(CXX) -o $@ $^ $(CXXFLAGS) $(LIBS)
clean:
rm -f $(EXE) $(OBJS)

View File

@ -0,0 +1,166 @@
// ImGui - standalone example application for GLFW + Metal, 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 "imgui_impl_glfw.h"
#include "imgui_impl_metal.h"
#define GLFW_INCLUDE_NONE
#define GLFW_EXPOSE_NATIVE_COCOA
#include <GLFW/glfw3.h>
#include <GLFW/glfw3native.h>
#import <Metal/Metal.h>
#import <QuartzCore/QuartzCore.h>
#include <stdio.h>
static void glfw_error_callback(int error, const char* description)
{
fprintf(stderr, "Glfw Error %d: %s\n", error, description);
}
int main(int, char**)
{
// Setup Dear ImGui binding
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
// Setup style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
// - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
// - Read 'misc/fonts/README.txt' for more instructions and details.
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
//io.Fonts->AddFontDefault();
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f);
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese());
//IM_ASSERT(font != NULL);
// Setup window
glfwSetErrorCallback(glfw_error_callback);
if (!glfwInit())
return 1;
// Create window with graphics context
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
GLFWwindow* window = glfwCreateWindow(1280, 720, "Dear ImGui GLFW+Metal example", NULL, NULL);
if (window == NULL)
return 1;
id <MTLDevice> device = MTLCreateSystemDefaultDevice();;
id <MTLCommandQueue> commandQueue = [device newCommandQueue];
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplMetal_Init(device);
NSWindow *nswin = glfwGetCocoaWindow(window);
CAMetalLayer *layer = [CAMetalLayer layer];
layer.device = device;
layer.pixelFormat = MTLPixelFormatBGRA8Unorm;
nswin.contentView.layer = layer;
nswin.contentView.wantsLayer = YES;
MTLRenderPassDescriptor *renderPassDescriptor = [MTLRenderPassDescriptor new];
bool show_demo_window = true;
bool show_another_window = false;
float clear_color[4] = {0.45f, 0.55f, 0.60f, 1.00f};
// Main loop
while (!glfwWindowShouldClose(window))
{
// Poll and handle events (inputs, window resize, etc.)
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
glfwPollEvents();
int width, height;
glfwGetFramebufferSize(window, &width, &height);
layer.drawableSize = CGSizeMake(width, height);
id<CAMetalDrawable> drawable = [layer nextDrawable];
id<MTLCommandBuffer> commandBuffer = [commandQueue commandBuffer];
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
renderPassDescriptor.colorAttachments[0].texture = drawable.texture;
renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
id <MTLRenderCommandEncoder> renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
[renderEncoder pushDebugGroup:@"ImGui demo"];
// Start the Dear ImGui frame
ImGui_ImplMetal_NewFrame(renderPassDescriptor);
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
// 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!).
if (show_demo_window)
ImGui::ShowDemoWindow(&show_demo_window);
// 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window.
{
static float f = 0.0f;
static int counter = 0;
ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it.
ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too)
ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state
ImGui::Checkbox("Another Window", &show_another_window);
ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated)
counter++;
ImGui::SameLine();
ImGui::Text("counter = %d", counter);
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
ImGui::End();
}
// 3. Show another simple window.
if (show_another_window)
{
ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
ImGui::Text("Hello from another window!");
if (ImGui::Button("Close Me"))
show_another_window = false;
ImGui::End();
}
// Rendering
ImGui::Render();
ImGui_ImplMetal_RenderDrawData(ImGui::GetDrawData(), commandBuffer, renderEncoder);
[renderEncoder popDebugGroup];
[renderEncoder endEncoding];
[commandBuffer presentDrawable:drawable];
[commandBuffer commit];
}
// Cleanup
ImGui_ImplMetal_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}

View File

@ -19,39 +19,46 @@ SOURCES = main.cpp
SOURCES += ../imgui_impl_glfw.cpp ../imgui_impl_opengl2.cpp SOURCES += ../imgui_impl_glfw.cpp ../imgui_impl_opengl2.cpp
SOURCES += ../../imgui.cpp ../../imgui_demo.cpp ../../imgui_draw.cpp ../../imgui_widgets.cpp SOURCES += ../../imgui.cpp ../../imgui_demo.cpp ../../imgui_draw.cpp ../../imgui_widgets.cpp
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
UNAME_S := $(shell uname -s) UNAME_S := $(shell uname -s)
CXXFLAGS = -I../ -I../../
CXXFLAGS += -g -Wall -Wformat
LIBS =
##---------------------------------------------------------------------
## BUILD FLAGS PER PLATFORM
##---------------------------------------------------------------------
ifeq ($(UNAME_S), Linux) #LINUX ifeq ($(UNAME_S), Linux) #LINUX
ECHO_MESSAGE = "Linux" ECHO_MESSAGE = "Linux"
LIBS = -lGL `pkg-config --static --libs glfw3` LIBS += -lGL `pkg-config --static --libs glfw3`
CXXFLAGS = -I../ -I../../ `pkg-config --cflags glfw3` CXXFLAGS += `pkg-config --cflags glfw3`
CXXFLAGS += -Wall -Wformat
CFLAGS = $(CXXFLAGS) CFLAGS = $(CXXFLAGS)
endif 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 -lglfw3 LIBS += -L/usr/local/lib -L/opt/local/lib
LIBS += -L/usr/local/lib -lglfw #LIBS += -lglfw3
LIBS += -lglfw
CXXFLAGS = -I../ -I../../ -I/usr/local/include CXXFLAGS += -I/usr/local/include -I/opt/local/include
CXXFLAGS += -Wall -Wformat
CFLAGS = $(CXXFLAGS) CFLAGS = $(CXXFLAGS)
endif endif
ifeq ($(findstring MINGW,$(UNAME_S)),MINGW) ifeq ($(findstring MINGW,$(UNAME_S)),MINGW)
ECHO_MESSAGE = "Windows" ECHO_MESSAGE = "MinGW"
LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 LIBS += -lglfw3 -lgdi32 -lopengl32 -limm32
CXXFLAGS = -I../ -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` CXXFLAGS += -I../libs/gl3w `pkg-config --cflags glfw3`
CXXFLAGS += -Wall -Wformat
CFLAGS = $(CXXFLAGS) CFLAGS = $(CXXFLAGS)
endif endif
##---------------------------------------------------------------------
## BUILD RULES
##---------------------------------------------------------------------
%.o:%.cpp %.o:%.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $< $(CXX) $(CXXFLAGS) -c -o $@ $<

View File

@ -21,29 +21,34 @@
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{9CDA7840-B7A5-496D-A527-E95571496D18}</ProjectGuid> <ProjectGuid>{9CDA7840-B7A5-496D-A527-E95571496D18}</ProjectGuid>
<RootNamespace>example_glfw_opengl2</RootNamespace> <RootNamespace>example_glfw_opengl2</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">
@ -85,11 +90,11 @@
<ClCompile> <ClCompile>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..;..;$(SolutionDir)\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>..\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>opengl32.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>opengl32.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries> <IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
@ -99,11 +104,11 @@
<ClCompile> <ClCompile>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..;..;$(SolutionDir)\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>..\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>opengl32.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>opengl32.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries> <IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
@ -115,14 +120,14 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..;..;$(SolutionDir)\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>..\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>opengl32.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>opengl32.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<IgnoreSpecificDefaultLibraries> <IgnoreSpecificDefaultLibraries>
@ -135,14 +140,14 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..;..;$(SolutionDir)\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>..\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>opengl32.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>opengl32.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<IgnoreSpecificDefaultLibraries> <IgnoreSpecificDefaultLibraries>

View File

@ -10,6 +10,9 @@
#include "imgui_impl_glfw.h" #include "imgui_impl_glfw.h"
#include "imgui_impl_opengl2.h" #include "imgui_impl_opengl2.h"
#include <stdio.h> #include <stdio.h>
#ifdef __APPLE__
#define GL_SILENCE_DEPRECATION
#endif
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
// [Win32] Our example includes a copy of glfw3.lib pre-compiled with VS2010 to maximize ease of testing and compatibility with old VS compilers. // [Win32] Our example includes a copy of glfw3.lib pre-compiled with VS2010 to maximize ease of testing and compatibility with old VS compilers.
@ -129,8 +132,14 @@ int main(int, char**)
glViewport(0, 0, display_w, display_h); glViewport(0, 0, display_w, display_h);
glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
//glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound, but prefer using the GL3+ code.
// If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!),
// you may need to backup/reset/restore current shader using the commented lines below.
//GLint last_program;
//glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
//glUseProgram(0);
ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData()); ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData());
//glUseProgram(last_program);
glfwMakeContextCurrent(window); glfwMakeContextCurrent(window);
glfwSwapBuffers(window); glfwSwapBuffers(window);

View File

@ -21,13 +21,17 @@ SOURCES += ../../imgui.cpp ../../imgui_demo.cpp ../../imgui_draw.cpp ../../imgui
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
UNAME_S := $(shell uname -s) UNAME_S := $(shell uname -s)
CXXFLAGS = -I../ -I../../
CXXFLAGS += -g -Wall -Wformat
LIBS =
##--------------------------------------------------------------------- ##---------------------------------------------------------------------
## OPENGL LOADER ## OPENGL LOADER
##--------------------------------------------------------------------- ##---------------------------------------------------------------------
## Using OpenGL loader: gl3w [default] ## Using OpenGL loader: gl3w [default]
SOURCES += ../libs/gl3w/GL/gl3w.c SOURCES += ../libs/gl3w/GL/gl3w.c
CXXFLAGS = -I../libs/gl3w CXXFLAGS += -I../libs/gl3w
## Using OpenGL loader: glew ## Using OpenGL loader: glew
## (This assumes a system-wide installation) ## (This assumes a system-wide installation)
@ -44,30 +48,28 @@ CXXFLAGS = -I../libs/gl3w
ifeq ($(UNAME_S), Linux) #LINUX ifeq ($(UNAME_S), Linux) #LINUX
ECHO_MESSAGE = "Linux" ECHO_MESSAGE = "Linux"
LIBS = -lGL `pkg-config --static --libs glfw3` LIBS += -lGL `pkg-config --static --libs glfw3`
CXXFLAGS += -I../ -I../../ `pkg-config --cflags glfw3` CXXFLAGS += `pkg-config --cflags glfw3`
CXXFLAGS += -Wall -Wformat
CFLAGS = $(CXXFLAGS) CFLAGS = $(CXXFLAGS)
endif 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 -lglfw3 LIBS += -L/usr/local/lib -L/opt/local/lib
LIBS += -L/usr/local/lib -lglfw #LIBS += -lglfw3
LIBS += -lglfw
CXXFLAGS += -I../ -I../../ -I/usr/local/include CXXFLAGS += -I/usr/local/include -I/opt/local/include
CXXFLAGS += -Wall -Wformat
CFLAGS = $(CXXFLAGS) CFLAGS = $(CXXFLAGS)
endif endif
ifeq ($(findstring MINGW,$(UNAME_S)),MINGW) ifeq ($(findstring MINGW,$(UNAME_S)),MINGW)
ECHO_MESSAGE = "Windows" ECHO_MESSAGE = "MinGW"
LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 LIBS += -lglfw3 -lgdi32 -lopengl32 -limm32
CXXFLAGS += -I../ -I../../ `pkg-config --cflags glfw3` CXXFLAGS += `pkg-config --cflags glfw3`
CXXFLAGS += -Wall -Wformat
CFLAGS = $(CXXFLAGS) CFLAGS = $(CXXFLAGS)
endif endif

View File

@ -21,29 +21,34 @@
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{4a1fb5ea-22f5-42a8-ab92-1d2df5d47fb9}</ProjectGuid> <ProjectGuid>{4a1fb5ea-22f5-42a8-ab92-1d2df5d47fb9}</ProjectGuid>
<RootNamespace>example_glfw_opengl3</RootNamespace> <RootNamespace>example_glfw_opengl3</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">
@ -85,11 +90,11 @@
<ClCompile> <ClCompile>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..;..;$(SolutionDir)\libs\glfw\include;$(SolutionDir)\libs\gl3w;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;..\libs\glfw\include;..\libs\gl3w;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>..\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>opengl32.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>opengl32.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries> <IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
@ -99,11 +104,11 @@
<ClCompile> <ClCompile>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..;..;$(SolutionDir)\libs\glfw\include;$(SolutionDir)\libs\gl3w;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;..\libs\glfw\include;..\libs\gl3w;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>..\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>opengl32.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>opengl32.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries> <IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
@ -115,14 +120,14 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..;..;$(SolutionDir)\libs\glfw\include;$(SolutionDir)\libs\gl3w;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;..\libs\glfw\include;..\libs\gl3w;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>..\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>opengl32.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>opengl32.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<IgnoreSpecificDefaultLibraries> <IgnoreSpecificDefaultLibraries>
@ -135,14 +140,14 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..;..;$(SolutionDir)\libs\glfw\include;$(SolutionDir)\libs\gl3w;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;..\libs\glfw\include;..\libs\gl3w;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>..\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>opengl32.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>opengl32.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<IgnoreSpecificDefaultLibraries> <IgnoreSpecificDefaultLibraries>

View File

@ -171,14 +171,12 @@ int main(int, char**)
// Rendering // Rendering
ImGui::Render(); ImGui::Render();
int display_w, display_h; int display_w, display_h;
glfwMakeContextCurrent(window);
glfwGetFramebufferSize(window, &display_w, &display_h); glfwGetFramebufferSize(window, &display_w, &display_h);
glViewport(0, 0, display_w, display_h); glViewport(0, 0, display_w, display_h);
glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
glfwMakeContextCurrent(window);
glfwSwapBuffers(window); glfwSwapBuffers(window);
} }

View File

@ -1,3 +1,8 @@
# Example usage:
# mkdir build
# cd build
# cmake -g "Visual Studio 14 2015" ..
cmake_minimum_required(VERSION 2.8) cmake_minimum_required(VERSION 2.8)
project(imgui_example_glfw_vulkan C CXX) project(imgui_example_glfw_vulkan C CXX)
@ -18,7 +23,7 @@ option(GLFW_DOCUMENT_INTERNALS "Include internals in documentation" OFF)
add_subdirectory(${GLFW_DIR} binary_dir EXCLUDE_FROM_ALL) add_subdirectory(${GLFW_DIR} binary_dir EXCLUDE_FROM_ALL)
include_directories(${GLFW_DIR}/include) include_directories(${GLFW_DIR}/include)
# ImGui # Dear ImGui
set(IMGUI_DIR ../../) set(IMGUI_DIR ../../)
include_directories(${IMGUI_DIR} ..) include_directories(${IMGUI_DIR} ..)

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32"> <ProjectConfiguration Include="Debug|Win32">
@ -21,29 +21,34 @@
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{57E2DF5A-6FC8-45BB-99DD-91A18C646E80}</ProjectGuid> <ProjectGuid>{57E2DF5A-6FC8-45BB-99DD-91A18C646E80}</ProjectGuid>
<RootNamespace>example_glfw_vulkan</RootNamespace> <RootNamespace>example_glfw_vulkan</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">
@ -85,11 +90,11 @@
<ClCompile> <ClCompile>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..;..;%VULKAN_SDK%\include;$(SolutionDir)\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>%VULKAN_SDK%\lib32;$(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>%VULKAN_SDK%\lib32;..\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>vulkan-1.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>vulkan-1.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries> <IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
@ -99,11 +104,11 @@
<ClCompile> <ClCompile>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..;..;%VULKAN_SDK%\include;$(SolutionDir)\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>%VULKAN_SDK%\lib;$(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>%VULKAN_SDK%\lib;..\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>vulkan-1.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>vulkan-1.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries> <IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
@ -115,14 +120,14 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..;..;%VULKAN_SDK%\include;$(SolutionDir)\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>%VULKAN_SDK%\lib32;$(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>%VULKAN_SDK%\lib32;..\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>vulkan-1.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>vulkan-1.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<IgnoreSpecificDefaultLibraries> <IgnoreSpecificDefaultLibraries>
@ -135,14 +140,14 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..;..;%VULKAN_SDK%\include;$(SolutionDir)\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>%VULKAN_SDK%\lib;$(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>%VULKAN_SDK%\lib;..\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>vulkan-1.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>vulkan-1.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<IgnoreSpecificDefaultLibraries> <IgnoreSpecificDefaultLibraries>

View File

@ -1,6 +1,13 @@
// dear imgui: standalone example application for Glfw + Vulkan // dear imgui: standalone example application for Glfw + Vulkan
// If you are new to dear imgui, see examples/README.txt and documentation at the top of imgui.cpp. // If you are new to dear imgui, see examples/README.txt and documentation at the top of imgui.cpp.
// Important note to the reader who wish to integrate imgui_impl_vulkan.cpp/.h in their own engine/app.
// - Common ImGui_ImplVulkan_XXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h.
// You will use those if you want to use this rendering back-end in your engine/app.
// - Helper ImGui_ImplVulkanH_XXX functions and structures are only used by this example (main.cpp) and by
// the back-end itself (imgui_impl_vulkan.cpp), but should PROBABLY NOT be used by your own engine/app code.
// Read comments in imgui_impl_vulkan.h.
#include "imgui.h" #include "imgui.h"
#include "imgui_impl_glfw.h" #include "imgui_impl_glfw.h"
#include "imgui_impl_vulkan.h" #include "imgui_impl_vulkan.h"
@ -33,9 +40,11 @@ static VkDebugReportCallbackEXT g_DebugReport = VK_NULL_HANDLE;
static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE; static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE;
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE; static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
static ImGui_ImplVulkanH_WindowData g_WindowData; static ImGui_ImplVulkanH_Window g_MainWindowData;
static bool g_ResizeWanted = false; static int g_MinImageCount = 2;
static int g_ResizeWidth = 0, g_ResizeHeight = 0; static bool g_SwapChainRebuild = false;
static int g_SwapChainResizeWidth = 0;
static int g_SwapChainResizeHeight = 0;
static void check_vk_result(VkResult err) static void check_vk_result(VkResult err)
{ {
@ -99,6 +108,7 @@ static void SetupVulkan(const char** extensions, uint32_t extensions_count)
// Create Vulkan Instance without any debug feature // Create Vulkan Instance without any debug feature
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
check_vk_result(err); check_vk_result(err);
IM_UNUSED(g_DebugReport);
#endif #endif
} }
@ -107,6 +117,7 @@ static void SetupVulkan(const char** extensions, uint32_t extensions_count)
uint32_t gpu_count; uint32_t gpu_count;
err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, NULL); err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, NULL);
check_vk_result(err); check_vk_result(err);
IM_ASSERT(gpu_count > 0);
VkPhysicalDevice* gpus = (VkPhysicalDevice*)malloc(sizeof(VkPhysicalDevice) * gpu_count); VkPhysicalDevice* gpus = (VkPhysicalDevice*)malloc(sizeof(VkPhysicalDevice) * gpu_count);
err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus); err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus);
@ -132,7 +143,7 @@ static void SetupVulkan(const char** extensions, uint32_t extensions_count)
break; break;
} }
free(queues); free(queues);
IM_ASSERT(g_QueueFamily != -1); IM_ASSERT(g_QueueFamily != (uint32_t)-1);
} }
// Create Logical Device (with 1 queue) // Create Logical Device (with 1 queue)
@ -183,7 +194,9 @@ static void SetupVulkan(const char** extensions, uint32_t extensions_count)
} }
} }
static void SetupVulkanWindowData(ImGui_ImplVulkanH_WindowData* wd, VkSurfaceKHR surface, int width, int height) // All the ImGui_ImplVulkanH_XXX structures/functions are optional helpers used by the demo.
// Your real engine/app may not use them.
static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface, int width, int height)
{ {
wd->Surface = surface; wd->Surface = surface;
@ -211,14 +224,12 @@ static void SetupVulkanWindowData(ImGui_ImplVulkanH_WindowData* wd, VkSurfaceKHR
//printf("[vulkan] Selected PresentMode = %d\n", wd->PresentMode); //printf("[vulkan] Selected PresentMode = %d\n", wd->PresentMode);
// Create SwapChain, RenderPass, Framebuffer, etc. // Create SwapChain, RenderPass, Framebuffer, etc.
ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(g_PhysicalDevice, g_Device, g_QueueFamily, wd, g_Allocator); IM_ASSERT(g_MinImageCount >= 2);
ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(g_PhysicalDevice, g_Device, wd, g_Allocator, width, height); ImGui_ImplVulkanH_CreateWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount);
} }
static void CleanupVulkan() static void CleanupVulkan()
{ {
ImGui_ImplVulkanH_WindowData* wd = &g_WindowData;
ImGui_ImplVulkanH_DestroyWindowData(g_Instance, g_Device, wd, g_Allocator);
vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator); vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator);
#ifdef IMGUI_VULKAN_DEBUG_REPORT #ifdef IMGUI_VULKAN_DEBUG_REPORT
@ -231,15 +242,21 @@ static void CleanupVulkan()
vkDestroyInstance(g_Instance, g_Allocator); vkDestroyInstance(g_Instance, g_Allocator);
} }
static void FrameRender(ImGui_ImplVulkanH_WindowData* wd) static void CleanupVulkanWindow()
{
ImGui_ImplVulkanH_DestroyWindow(g_Instance, g_Device, &g_MainWindowData, g_Allocator);
}
static void FrameRender(ImGui_ImplVulkanH_Window* wd)
{ {
VkResult err; VkResult err;
VkSemaphore& image_acquired_semaphore = wd->Frames[wd->FrameIndex].ImageAcquiredSemaphore; VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore;
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex); err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
check_vk_result(err); check_vk_result(err);
ImGui_ImplVulkanH_FrameData* fd = &wd->Frames[wd->FrameIndex]; ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex];
{ {
err = vkWaitForFences(g_Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX); // wait indefinitely instead of periodically checking err = vkWaitForFences(g_Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX); // wait indefinitely instead of periodically checking
check_vk_result(err); check_vk_result(err);
@ -260,7 +277,7 @@ static void FrameRender(ImGui_ImplVulkanH_WindowData* wd)
VkRenderPassBeginInfo info = {}; VkRenderPassBeginInfo info = {};
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
info.renderPass = wd->RenderPass; info.renderPass = wd->RenderPass;
info.framebuffer = wd->Framebuffer[wd->FrameIndex]; info.framebuffer = fd->Framebuffer;
info.renderArea.extent.width = wd->Width; info.renderArea.extent.width = wd->Width;
info.renderArea.extent.height = wd->Height; info.renderArea.extent.height = wd->Height;
info.clearValueCount = 1; info.clearValueCount = 1;
@ -283,7 +300,7 @@ static void FrameRender(ImGui_ImplVulkanH_WindowData* wd)
info.commandBufferCount = 1; info.commandBufferCount = 1;
info.pCommandBuffers = &fd->CommandBuffer; info.pCommandBuffers = &fd->CommandBuffer;
info.signalSemaphoreCount = 1; info.signalSemaphoreCount = 1;
info.pSignalSemaphores = &fd->RenderCompleteSemaphore; info.pSignalSemaphores = &render_complete_semaphore;
err = vkEndCommandBuffer(fd->CommandBuffer); err = vkEndCommandBuffer(fd->CommandBuffer);
check_vk_result(err); check_vk_result(err);
@ -292,18 +309,19 @@ static void FrameRender(ImGui_ImplVulkanH_WindowData* wd)
} }
} }
static void FramePresent(ImGui_ImplVulkanH_WindowData* wd) static void FramePresent(ImGui_ImplVulkanH_Window* wd)
{ {
ImGui_ImplVulkanH_FrameData* fd = &wd->Frames[wd->FrameIndex]; VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
VkPresentInfoKHR info = {}; VkPresentInfoKHR info = {};
info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
info.waitSemaphoreCount = 1; info.waitSemaphoreCount = 1;
info.pWaitSemaphores = &fd->RenderCompleteSemaphore; info.pWaitSemaphores = &render_complete_semaphore;
info.swapchainCount = 1; info.swapchainCount = 1;
info.pSwapchains = &wd->Swapchain; info.pSwapchains = &wd->Swapchain;
info.pImageIndices = &wd->FrameIndex; info.pImageIndices = &wd->FrameIndex;
VkResult err = vkQueuePresentKHR(g_Queue, &info); VkResult err = vkQueuePresentKHR(g_Queue, &info);
check_vk_result(err); check_vk_result(err);
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->ImageCount; // Now we can use the next set of semaphores
} }
static void glfw_error_callback(int error, const char* description) static void glfw_error_callback(int error, const char* description)
@ -313,14 +331,14 @@ static void glfw_error_callback(int error, const char* description)
static void glfw_resize_callback(GLFWwindow*, int w, int h) static void glfw_resize_callback(GLFWwindow*, int w, int h)
{ {
g_ResizeWanted = true; g_SwapChainRebuild = true;
g_ResizeWidth = w; g_SwapChainResizeWidth = w;
g_ResizeHeight = h; g_SwapChainResizeHeight = h;
} }
int main(int, char**) int main(int, char**)
{ {
// Setup window // Setup GLFW window
glfwSetErrorCallback(glfw_error_callback); glfwSetErrorCallback(glfw_error_callback);
if (!glfwInit()) if (!glfwInit())
return 1; return 1;
@ -347,8 +365,8 @@ int main(int, char**)
int w, h; int w, h;
glfwGetFramebufferSize(window, &w, &h); glfwGetFramebufferSize(window, &w, &h);
glfwSetFramebufferSizeCallback(window, glfw_resize_callback); glfwSetFramebufferSizeCallback(window, glfw_resize_callback);
ImGui_ImplVulkanH_WindowData* wd = &g_WindowData; ImGui_ImplVulkanH_Window* wd = &g_MainWindowData;
SetupVulkanWindowData(wd, surface, w, h); SetupVulkanWindow(wd, surface, w, h);
// Setup Dear ImGui context // Setup Dear ImGui context
IMGUI_CHECKVERSION(); IMGUI_CHECKVERSION();
@ -372,6 +390,8 @@ int main(int, char**)
init_info.PipelineCache = g_PipelineCache; init_info.PipelineCache = g_PipelineCache;
init_info.DescriptorPool = g_DescriptorPool; init_info.DescriptorPool = g_DescriptorPool;
init_info.Allocator = g_Allocator; init_info.Allocator = g_Allocator;
init_info.MinImageCount = g_MinImageCount;
init_info.ImageCount = wd->ImageCount;
init_info.CheckVkResultFn = check_vk_result; init_info.CheckVkResultFn = check_vk_result;
ImGui_ImplVulkan_Init(&init_info, wd->RenderPass); ImGui_ImplVulkan_Init(&init_info, wd->RenderPass);
@ -417,7 +437,7 @@ int main(int, char**)
err = vkDeviceWaitIdle(g_Device); err = vkDeviceWaitIdle(g_Device);
check_vk_result(err); check_vk_result(err);
ImGui_ImplVulkan_InvalidateFontUploadObjects(); ImGui_ImplVulkan_DestroyFontUploadObjects();
} }
bool show_demo_window = true; bool show_demo_window = true;
@ -433,10 +453,13 @@ int main(int, char**)
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
glfwPollEvents(); glfwPollEvents();
if (g_ResizeWanted)
if (g_SwapChainRebuild)
{ {
ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(g_PhysicalDevice, g_Device, &g_WindowData, g_Allocator, g_ResizeWidth, g_ResizeHeight); g_SwapChainRebuild = false;
g_ResizeWanted = false; ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount);
ImGui_ImplVulkanH_CreateWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, g_SwapChainResizeWidth, g_SwapChainResizeHeight, g_MinImageCount);
g_MainWindowData.FrameIndex = 0;
} }
// Start the Dear ImGui frame // Start the Dear ImGui frame
@ -495,6 +518,8 @@ int main(int, char**)
ImGui_ImplVulkan_Shutdown(); ImGui_ImplVulkan_Shutdown();
ImGui_ImplGlfw_Shutdown(); ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext(); ImGui::DestroyContext();
CleanupVulkanWindow();
CleanupVulkan(); CleanupVulkan();
glfwDestroyWindow(window); glfwDestroyWindow(window);

View File

@ -0,0 +1,68 @@
#
# Cross Platform Makefile
# Compatible with MSYS2/MINGW, Ubuntu 14.04.1 and Mac OS X
#
# Linux:
# apt-get install freeglut3-dev
#
#CXX = g++
#CXX = clang++
EXE = example_glut_opengl2
SOURCES = main.cpp
SOURCES += ../imgui_impl_glut.cpp ../imgui_impl_opengl2.cpp
SOURCES += ../../imgui.cpp ../../imgui_demo.cpp ../../imgui_draw.cpp ../../imgui_widgets.cpp
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
UNAME_S := $(shell uname -s)
CXXFLAGS = -I../ -I../../
CXXFLAGS += -g -Wall -Wformat
LIBS =
##---------------------------------------------------------------------
## BUILD FLAGS PER PLATFORM
##---------------------------------------------------------------------
ifeq ($(UNAME_S), Linux) #LINUX
ECHO_MESSAGE = "Linux"
LIBS += -lGL -lglut
CFLAGS = $(CXXFLAGS)
endif
ifeq ($(UNAME_S), Darwin) #APPLE
ECHO_MESSAGE = "Mac OS X"
LIBS += -framework OpenGL -framework GLUT
LIBS += -L/usr/local/lib -L/opt/local/lib
CXXFLAGS += -I/usr/local/include -I/opt/local/include
CFLAGS = $(CXXFLAGS)
endif
ifeq ($(findstring MINGW,$(UNAME_S)),MINGW)
ECHO_MESSAGE = "MinGW"
LIBS += -lgdi32 -lopengl32 -limm32 -lglut
CFLAGS = $(CXXFLAGS)
endif
##---------------------------------------------------------------------
## BUILD RULES
##---------------------------------------------------------------------
%.o:%.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
%.o:../%.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
%.o:../../%.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
all: $(EXE)
@echo Build complete for $(ECHO_MESSAGE)
$(EXE): $(OBJS)
$(CXX) -o $@ $^ $(CXXFLAGS) $(LIBS)
clean:
rm -f $(EXE) $(OBJS)

View File

@ -20,30 +20,35 @@
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{F90D0333-5FB1-440D-918D-DD39A1B5187E}</ProjectGuid> <ProjectGuid>{F90D0333-5FB1-440D-918D-DD39A1B5187E}</ProjectGuid>
<RootNamespace>example_freeglut_opengl2</RootNamespace> <RootNamespace>example_glut_opengl2</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">
@ -154,7 +159,7 @@
<ClCompile Include="..\..\imgui_demo.cpp" /> <ClCompile Include="..\..\imgui_demo.cpp" />
<ClCompile Include="..\..\imgui_draw.cpp" /> <ClCompile Include="..\..\imgui_draw.cpp" />
<ClCompile Include="..\..\imgui_widgets.cpp" /> <ClCompile Include="..\..\imgui_widgets.cpp" />
<ClCompile Include="..\imgui_impl_freeglut.cpp" /> <ClCompile Include="..\imgui_impl_glut.cpp" />
<ClCompile Include="..\imgui_impl_opengl2.cpp" /> <ClCompile Include="..\imgui_impl_opengl2.cpp" />
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />
</ItemGroup> </ItemGroup>
@ -162,7 +167,7 @@
<ClInclude Include="..\..\imconfig.h" /> <ClInclude Include="..\..\imconfig.h" />
<ClInclude Include="..\..\imgui.h" /> <ClInclude Include="..\..\imgui.h" />
<ClInclude Include="..\..\imgui_internal.h" /> <ClInclude Include="..\..\imgui_internal.h" />
<ClInclude Include="..\imgui_impl_freeglut.h" /> <ClInclude Include="..\imgui_impl_glut.h" />
<ClInclude Include="..\imgui_impl_opengl2.h" /> <ClInclude Include="..\imgui_impl_opengl2.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -22,7 +22,7 @@
<ClCompile Include="..\..\imgui_draw.cpp"> <ClCompile Include="..\..\imgui_draw.cpp">
<Filter>imgui</Filter> <Filter>imgui</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\imgui_impl_freeglut.cpp"> <ClCompile Include="..\imgui_impl_glut.cpp">
<Filter>sources</Filter> <Filter>sources</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\imgui_impl_opengl2.cpp"> <ClCompile Include="..\imgui_impl_opengl2.cpp">
@ -42,7 +42,7 @@
<ClInclude Include="..\..\imgui_internal.h"> <ClInclude Include="..\..\imgui_internal.h">
<Filter>imgui</Filter> <Filter>imgui</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\imgui_impl_freeglut.h"> <ClInclude Include="..\imgui_impl_glut.h">
<Filter>sources</Filter> <Filter>sources</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\imgui_impl_opengl2.h"> <ClInclude Include="..\imgui_impl_opengl2.h">

View File

@ -1,11 +1,18 @@
// dear imgui: standalone example application for FreeGLUT + OpenGL2, using legacy fixed pipeline // dear imgui: standalone example application for GLUT/FreeGLUT + OpenGL2, using legacy fixed pipeline
// If you are new to dear imgui, see examples/README.txt and documentation at the top of imgui.cpp. // If you are new to dear imgui, see examples/README.txt and documentation at the top of imgui.cpp.
// (Using GLUT or FreeGLUT is not recommended unless you really miss the 90's)
// !!! GLUT/FreeGLUT IS OBSOLETE SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!!
// !!! If someone or something is teaching you GLUT in 2019, you are being abused. Please show some resistance. !!!
// !!! Nowadays, prefer using GLFW or SDL instead!
#include "imgui.h" #include "imgui.h"
#include "../imgui_impl_freeglut.h" #include "../imgui_impl_glut.h"
#include "../imgui_impl_opengl2.h" #include "../imgui_impl_opengl2.h"
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/freeglut.h> #include <GL/freeglut.h>
#endif
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning (disable: 4505) // unreferenced local function has been removed #pragma warning (disable: 4505) // unreferenced local function has been removed
@ -59,7 +66,7 @@ void glut_display_func()
{ {
// Start the Dear ImGui frame // Start the Dear ImGui frame
ImGui_ImplOpenGL2_NewFrame(); ImGui_ImplOpenGL2_NewFrame();
ImGui_ImplFreeGLUT_NewFrame(); ImGui_ImplGLUT_NewFrame();
my_display_code(); my_display_code();
@ -85,14 +92,16 @@ int main(int argc, char** argv)
{ {
// Create GLUT window // Create GLUT window
glutInit(&argc, argv); glutInit(&argc, argv);
#ifdef __FREEGLUT_EXT_H__
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS); glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
#endif
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_MULTISAMPLE); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_MULTISAMPLE);
glutInitWindowSize(1280, 720); glutInitWindowSize(1280, 720);
glutCreateWindow("Dear ImGui FreeGLUT+OpenGL2 Example"); glutCreateWindow("Dear ImGui GLUT+OpenGL2 Example");
// Setup GLUT display function // Setup GLUT display function
// We will also call ImGui_ImplFreeGLUT_InstallFuncs() to get all the other functions installed for us, // We will also call ImGui_ImplGLUT_InstallFuncs() to get all the other functions installed for us,
// otherwise it is possible to install our own functions and call the imgui_impl_freeglut.h functions ourselves. // otherwise it is possible to install our own functions and call the imgui_impl_glut.h functions ourselves.
glutDisplayFunc(glut_display_func); glutDisplayFunc(glut_display_func);
// Setup Dear ImGui context // Setup Dear ImGui context
@ -105,8 +114,8 @@ int main(int argc, char** argv)
//ImGui::StyleColorsClassic(); //ImGui::StyleColorsClassic();
// Setup Platform/Renderer bindings // Setup Platform/Renderer bindings
ImGui_ImplFreeGLUT_Init(); ImGui_ImplGLUT_Init();
ImGui_ImplFreeGLUT_InstallFuncs(); ImGui_ImplGLUT_InstallFuncs();
ImGui_ImplOpenGL2_Init(); ImGui_ImplOpenGL2_Init();
// Load Fonts // Load Fonts
@ -128,7 +137,7 @@ int main(int argc, char** argv)
// Cleanup // Cleanup
ImGui_ImplOpenGL2_Shutdown(); ImGui_ImplOpenGL2_Shutdown();
ImGui_ImplFreeGLUT_Shutdown(); ImGui_ImplGLUT_Shutdown();
ImGui::DestroyContext(); ImGui::DestroyContext();
return 0; return 0;

View File

@ -0,0 +1,59 @@
#
# Cross Platform Makefile
# Compatible with MSYS2/MINGW, Ubuntu 14.04.1 and Mac OS X
#
EXE = example_null
SOURCES = main.cpp
SOURCES += ../../imgui.cpp ../../imgui_demo.cpp ../../imgui_draw.cpp ../../imgui_widgets.cpp
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
UNAME_S := $(shell uname -s)
CXXFLAGS = -I../ -I../../
CXXFLAGS += -g -Wall -Wformat
LIBS =
##---------------------------------------------------------------------
## BUILD FLAGS PER PLATFORM
##---------------------------------------------------------------------
ifeq ($(UNAME_S), Linux) #LINUX
ECHO_MESSAGE = "Linux"
CFLAGS = $(CXXFLAGS)
endif
ifeq ($(UNAME_S), Darwin) #APPLE
ECHO_MESSAGE = "Mac OS X"
CFLAGS = $(CXXFLAGS)
endif
ifeq ($(findstring MINGW,$(UNAME_S)),MINGW)
ECHO_MESSAGE = "MinGW"
CFLAGS = $(CXXFLAGS)
endif
##---------------------------------------------------------------------
## BUILD RULES
##---------------------------------------------------------------------
%.o:%.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
%.o:../%.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
%.o:../../%.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
%.o:../libs/gl3w/GL/%.c
# %.o:../libs/glad/src/%.c
$(CC) $(CFLAGS) -c -o $@ $<
all: $(EXE)
@echo Build complete for $(ECHO_MESSAGE)
$(EXE): $(OBJS)
$(CXX) -o $@ $^ $(CXXFLAGS) $(LIBS)
clean:
rm -f $(EXE) $(OBJS)

View File

@ -1,4 +1,6 @@
// dear imgui: null/dummy example application (compile and link imgui with no inputs, no outputs) // dear imgui: null/dummy example application
// (compile and link imgui, create context, run headless with NO INPUTS, NO GRAPHICS OUTPUT)
// This is useful to test building, but you cannot interact with anything here!
#include "imgui.h" #include "imgui.h"
#include <stdio.h> #include <stdio.h>
@ -13,7 +15,7 @@ int main(int, char**)
int tex_w, tex_h; int tex_w, tex_h;
io.Fonts->GetTexDataAsRGBA32(&tex_pixels, &tex_w, &tex_h); io.Fonts->GetTexDataAsRGBA32(&tex_pixels, &tex_w, &tex_h);
for (int n = 0; n < 50; n++) for (int n = 0; n < 20; n++)
{ {
printf("NewFrame() %d\n", n); printf("NewFrame() %d\n", n);
io.DisplaySize = ImVec2(1920, 1080); io.DisplaySize = ImVec2(1920, 1080);

View File

@ -15,40 +15,49 @@
#CXX = clang++ #CXX = clang++
EXE = example_sdl_opengl2 EXE = example_sdl_opengl2
SOURCES = main.cpp ../imgui_impl_sdl.cpp ../imgui_impl_opengl2.cpp SOURCES = main.cpp
SOURCES += ../imgui_impl_sdl.cpp ../imgui_impl_opengl2.cpp
SOURCES += ../../imgui.cpp ../../imgui_demo.cpp ../../imgui_draw.cpp ../../imgui_widgets.cpp SOURCES += ../../imgui.cpp ../../imgui_demo.cpp ../../imgui_draw.cpp ../../imgui_widgets.cpp
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
UNAME_S := $(shell uname -s) UNAME_S := $(shell uname -s)
CXXFLAGS = -I../ -I../../
CXXFLAGS += -g -Wall -Wformat
LIBS =
##---------------------------------------------------------------------
## BUILD FLAGS PER PLATFORM
##---------------------------------------------------------------------
ifeq ($(UNAME_S), Linux) #LINUX ifeq ($(UNAME_S), Linux) #LINUX
ECHO_MESSAGE = "Linux" ECHO_MESSAGE = "Linux"
LIBS = -lGL -ldl `sdl2-config --libs` LIBS += -lGL -ldl `sdl2-config --libs`
CXXFLAGS = -I ../ -I../../ `sdl2-config --cflags` CXXFLAGS += `sdl2-config --cflags`
CXXFLAGS += -Wall -Wformat
CFLAGS = $(CXXFLAGS) CFLAGS = $(CXXFLAGS)
endif 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 `sdl2-config --libs` LIBS += -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo `sdl2-config --libs`
LIBS += -L/usr/local/lib -L/opt/local/lib
CXXFLAGS = -I ../ -I../../ -I/usr/local/include `sdl2-config --cflags` CXXFLAGS += `sdl2-config --cflags`
CXXFLAGS += -Wall -Wformat CXXFLAGS += -I/usr/local/include -I/opt/local/include
CFLAGS = $(CXXFLAGS) CFLAGS = $(CXXFLAGS)
endif endif
ifeq ($(findstring MINGW,$(UNAME_S)),MINGW) ifeq ($(findstring MINGW,$(UNAME_S)),MINGW)
ECHO_MESSAGE = "Windows" ECHO_MESSAGE = "MinGW"
LIBS = -lgdi32 -lopengl32 -limm32 `pkg-config --static --libs sdl2` LIBS += -lgdi32 -lopengl32 -limm32 `pkg-config --static --libs sdl2`
CXXFLAGS = -I ../ -I../../ `pkg-config --cflags sdl2` CXXFLAGS += `pkg-config --cflags sdl2`
CXXFLAGS += -Wall -Wformat
CFLAGS = $(CXXFLAGS) CFLAGS = $(CXXFLAGS)
endif endif
##---------------------------------------------------------------------
## BUILD RULES
##---------------------------------------------------------------------
%.o:%.cpp %.o:%.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $< $(CXX) $(CXXFLAGS) -c -o $@ $<

View File

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

View File

@ -19,31 +19,36 @@
</ProjectConfiguration> </ProjectConfiguration>
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{94E991D0-790A-4DAF-B442-AAADE3233C75}</ProjectGuid> <ProjectGuid>{2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741}</ProjectGuid>
<RootNamespace>example_sdl_opengl2</RootNamespace> <RootNamespace>example_sdl_opengl2</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">
@ -85,7 +90,7 @@
<ClCompile> <ClCompile>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..;..;%SDL2_DIR%\include;$(SolutionDir)\libs\gl3w;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;%SDL2_DIR%\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
@ -99,7 +104,7 @@
<ClCompile> <ClCompile>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..;..;%SDL2_DIR%\include;$(SolutionDir)\libs\gl3w;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;%SDL2_DIR%\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
@ -115,7 +120,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..;..;%SDL2_DIR%\include;$(SolutionDir)\libs\gl3w;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;%SDL2_DIR%\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
</ClCompile> </ClCompile>
<Link> <Link>
@ -135,7 +140,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..;..;%SDL2_DIR%\include;$(SolutionDir)\libs\gl3w;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;%SDL2_DIR%\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
</ClCompile> </ClCompile>
<Link> <Link>

View File

@ -16,7 +16,7 @@
int main(int, char**) int main(int, char**)
{ {
// Setup SDL // Setup SDL
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0) if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
{ {
printf("Error: %s\n", SDL_GetError()); printf("Error: %s\n", SDL_GetError());
return -1; return -1;
@ -28,10 +28,10 @@ int main(int, char**)
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, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_DisplayMode current; SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
SDL_GetCurrentDisplayMode(0, &current); SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
SDL_GLContext gl_context = SDL_GL_CreateContext(window); SDL_GLContext gl_context = SDL_GL_CreateContext(window);
SDL_GL_MakeCurrent(window, gl_context);
SDL_GL_SetSwapInterval(1); // Enable vsync SDL_GL_SetSwapInterval(1); // Enable vsync
// Setup Dear ImGui context // Setup Dear ImGui context
@ -39,6 +39,7 @@ int main(int, char**)
ImGui::CreateContext(); ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io; ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
// Setup Dear ImGui style // Setup Dear ImGui style
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();

View File

@ -21,13 +21,17 @@ SOURCES += ../../imgui.cpp ../../imgui_demo.cpp ../../imgui_draw.cpp ../../imgui
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
UNAME_S := $(shell uname -s) UNAME_S := $(shell uname -s)
CXXFLAGS = -I../ -I../../
CXXFLAGS += -g -Wall -Wformat
LIBS =
##--------------------------------------------------------------------- ##---------------------------------------------------------------------
## OPENGL LOADER ## OPENGL LOADER
##--------------------------------------------------------------------- ##---------------------------------------------------------------------
## Using OpenGL loader: gl3w [default] ## Using OpenGL loader: gl3w [default]
SOURCES += ../libs/gl3w/GL/gl3w.c SOURCES += ../libs/gl3w/GL/gl3w.c
CXXFLAGS = -I../libs/gl3w CXXFLAGS += -I../libs/gl3w
## Using OpenGL loader: glew ## Using OpenGL loader: glew
## (This assumes a system-wide installation) ## (This assumes a system-wide installation)
@ -44,28 +48,27 @@ CXXFLAGS = -I../libs/gl3w
ifeq ($(UNAME_S), Linux) #LINUX ifeq ($(UNAME_S), Linux) #LINUX
ECHO_MESSAGE = "Linux" ECHO_MESSAGE = "Linux"
LIBS = -lGL -ldl `sdl2-config --libs` LIBS += -lGL -ldl `sdl2-config --libs`
CXXFLAGS = -I../ -I../../ -I../libs/gl3w `sdl2-config --cflags` CXXFLAGS += -I../libs/gl3w `sdl2-config --cflags`
CXXFLAGS += -Wall -Wformat
CFLAGS = $(CXXFLAGS) CFLAGS = $(CXXFLAGS)
endif 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 `sdl2-config --libs` LIBS += -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo `sdl2-config --libs`
LIBS += -L/usr/local/lib -L/opt/local/lib
CXXFLAGS = -I../ -I../../ -I../libs/gl3w -I/usr/local/include `sdl2-config --cflags` CXXFLAGS += -I../libs/gl3w `sdl2-config --cflags`
CXXFLAGS += -Wall -Wformat CXXFLAGS += -I/usr/local/include -I/opt/local/include
CFLAGS = $(CXXFLAGS) CFLAGS = $(CXXFLAGS)
endif endif
ifeq ($(findstring MINGW,$(UNAME_S)),MINGW) ifeq ($(findstring MINGW,$(UNAME_S)),MINGW)
ECHO_MESSAGE = "Windows" ECHO_MESSAGE = "MinGW"
LIBS = -lgdi32 -lopengl32 -limm32 `pkg-config --static --libs sdl2` LIBS += -lgdi32 -lopengl32 -limm32 `pkg-config --static --libs sdl2`
CXXFLAGS = -I../ -I../../ -I../libs/gl3w `pkg-config --cflags sdl2` CXXFLAGS += -I../libs/gl3w `pkg-config --cflags sdl2`
CXXFLAGS += -Wall -Wformat
CFLAGS = $(CXXFLAGS) CFLAGS = $(CXXFLAGS)
endif endif

View File

@ -1,6 +1,6 @@
@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.
set OUT_DIR=Debug set OUT_DIR=Debug
set OUT_EXE=example_sdl_opengl3.exe set OUT_EXE=example_sdl_opengl3
set INCLUDES=/I.. /I..\.. /I%SDL2_DIR%\include /I..\libs\gl3w set INCLUDES=/I.. /I..\.. /I%SDL2_DIR%\include /I..\libs\gl3w
set SOURCES=main.cpp ..\imgui_impl_sdl.cpp ..\imgui_impl_opengl3.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c set SOURCES=main.cpp ..\imgui_impl_sdl.cpp ..\imgui_impl_opengl3.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c
set LIBS=/libpath:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib set LIBS=/libpath:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib

View File

@ -21,29 +21,34 @@
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{BBAEB705-1669-40F3-8567-04CF6A991F4C}</ProjectGuid> <ProjectGuid>{BBAEB705-1669-40F3-8567-04CF6A991F4C}</ProjectGuid>
<RootNamespace>example_sdl_opengl3</RootNamespace> <RootNamespace>example_sdl_opengl3</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">
@ -85,7 +90,7 @@
<ClCompile> <ClCompile>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..;..;%SDL2_DIR%\include;$(SolutionDir)\libs\gl3w;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;%SDL2_DIR%\include;..\libs\gl3w;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
@ -99,7 +104,7 @@
<ClCompile> <ClCompile>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..;..;%SDL2_DIR%\include;$(SolutionDir)\libs\gl3w;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;%SDL2_DIR%\include;..\libs\gl3w;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
@ -115,7 +120,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..;..;%SDL2_DIR%\include;$(SolutionDir)\libs\gl3w;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;%SDL2_DIR%\include;..\libs\gl3w;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
</ClCompile> </ClCompile>
<Link> <Link>
@ -135,7 +140,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..;..;%SDL2_DIR%\include;$(SolutionDir)\libs\gl3w;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;%SDL2_DIR%\include;..\libs\gl3w;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
</ClCompile> </ClCompile>
<Link> <Link>

View File

@ -25,7 +25,7 @@
int main(int, char**) int main(int, char**)
{ {
// Setup SDL // Setup SDL
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0) if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
{ {
printf("Error: %s\n", SDL_GetError()); printf("Error: %s\n", SDL_GetError());
return -1; return -1;
@ -52,10 +52,10 @@ int main(int, char**)
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_DisplayMode current; SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
SDL_GetCurrentDisplayMode(0, &current); SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL3 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL3 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
SDL_GLContext gl_context = SDL_GL_CreateContext(window); SDL_GLContext gl_context = SDL_GL_CreateContext(window);
SDL_GL_MakeCurrent(window, gl_context);
SDL_GL_SetSwapInterval(1); // Enable vsync SDL_GL_SetSwapInterval(1); // Enable vsync
// Initialize OpenGL loader // Initialize OpenGL loader
@ -79,6 +79,7 @@ int main(int, char**)
ImGui::CreateContext(); ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io; ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
// Setup Dear ImGui style // Setup Dear ImGui style
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
@ -170,7 +171,6 @@ int main(int, char**)
// Rendering // Rendering
ImGui::Render(); ImGui::Render();
SDL_GL_MakeCurrent(window, gl_context);
glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y); glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);

View File

@ -21,29 +21,34 @@
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3}</ProjectGuid> <ProjectGuid>{BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3}</ProjectGuid>
<RootNamespace>example_sdl_vulkan</RootNamespace> <RootNamespace>example_sdl_vulkan</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">

View File

@ -1,6 +1,13 @@
// dear imgui: standalone example application for SDL2 + Vulkan // dear imgui: standalone example application for SDL2 + Vulkan
// If you are new to dear imgui, see examples/README.txt and documentation at the top of imgui.cpp. // If you are new to dear imgui, see examples/README.txt and documentation at the top of imgui.cpp.
// Important note to the reader who wish to integrate imgui_impl_vulkan.cpp/.h in their own engine/app.
// - Common ImGui_ImplVulkan_XXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h.
// You will use those if you want to use this rendering back-end in your engine/app.
// - Helper ImGui_ImplVulkanH_XXX functions and structures are only used by this example (main.cpp) and by
// the back-end itself (imgui_impl_vulkan.cpp), but should PROBABLY NOT be used by your own engine/app code.
// Read comments in imgui_impl_vulkan.h.
#include "imgui.h" #include "imgui.h"
#include "imgui_impl_sdl.h" #include "imgui_impl_sdl.h"
#include "imgui_impl_vulkan.h" #include "imgui_impl_vulkan.h"
@ -25,7 +32,11 @@ static VkDebugReportCallbackEXT g_DebugReport = VK_NULL_HANDLE;
static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE; static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE;
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE; static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
static ImGui_ImplVulkanH_WindowData g_WindowData; static ImGui_ImplVulkanH_Window g_MainWindowData;
static uint32_t g_MinImageCount = 2;
static bool g_SwapChainRebuild = false;
static int g_SwapChainResizeWidth = 0;
static int g_SwapChainResizeHeight = 0;
static void check_vk_result(VkResult err) static void check_vk_result(VkResult err)
{ {
@ -89,6 +100,7 @@ static void SetupVulkan(const char** extensions, uint32_t extensions_count)
// Create Vulkan Instance without any debug feature // Create Vulkan Instance without any debug feature
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
check_vk_result(err); check_vk_result(err);
IM_UNUSED(g_DebugReport);
#endif #endif
} }
@ -97,6 +109,7 @@ static void SetupVulkan(const char** extensions, uint32_t extensions_count)
uint32_t gpu_count; uint32_t gpu_count;
err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, NULL); err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, NULL);
check_vk_result(err); check_vk_result(err);
IM_ASSERT(gpu_count > 0);
VkPhysicalDevice* gpus = (VkPhysicalDevice*)malloc(sizeof(VkPhysicalDevice) * gpu_count); VkPhysicalDevice* gpus = (VkPhysicalDevice*)malloc(sizeof(VkPhysicalDevice) * gpu_count);
err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus); err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus);
@ -122,7 +135,7 @@ static void SetupVulkan(const char** extensions, uint32_t extensions_count)
break; break;
} }
free(queues); free(queues);
IM_ASSERT(g_QueueFamily != -1); IM_ASSERT(g_QueueFamily != (uint32_t)-1);
} }
// Create Logical Device (with 1 queue) // Create Logical Device (with 1 queue)
@ -173,7 +186,9 @@ static void SetupVulkan(const char** extensions, uint32_t extensions_count)
} }
} }
static void SetupVulkanWindowData(ImGui_ImplVulkanH_WindowData* wd, VkSurfaceKHR surface, int width, int height) // All the ImGui_ImplVulkanH_XXX structures/functions are optional helpers used by the demo.
// Your real engine/app may not use them.
static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface, int width, int height)
{ {
wd->Surface = surface; wd->Surface = surface;
@ -201,14 +216,12 @@ static void SetupVulkanWindowData(ImGui_ImplVulkanH_WindowData* wd, VkSurfaceKHR
//printf("[vulkan] Selected PresentMode = %d\n", wd->PresentMode); //printf("[vulkan] Selected PresentMode = %d\n", wd->PresentMode);
// Create SwapChain, RenderPass, Framebuffer, etc. // Create SwapChain, RenderPass, Framebuffer, etc.
ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(g_PhysicalDevice, g_Device, g_QueueFamily, wd, g_Allocator); IM_ASSERT(g_MinImageCount >= 2);
ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(g_PhysicalDevice, g_Device, wd, g_Allocator, width, height); ImGui_ImplVulkanH_CreateWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount);
} }
static void CleanupVulkan() static void CleanupVulkan()
{ {
ImGui_ImplVulkanH_WindowData* wd = &g_WindowData;
ImGui_ImplVulkanH_DestroyWindowData(g_Instance, g_Device, wd, g_Allocator);
vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator); vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator);
#ifdef IMGUI_VULKAN_DEBUG_REPORT #ifdef IMGUI_VULKAN_DEBUG_REPORT
@ -221,15 +234,21 @@ static void CleanupVulkan()
vkDestroyInstance(g_Instance, g_Allocator); vkDestroyInstance(g_Instance, g_Allocator);
} }
static void FrameRender(ImGui_ImplVulkanH_WindowData* wd) static void CleanupVulkanWindow()
{
ImGui_ImplVulkanH_DestroyWindow(g_Instance, g_Device, &g_MainWindowData, g_Allocator);
}
static void FrameRender(ImGui_ImplVulkanH_Window* wd)
{ {
VkResult err; VkResult err;
VkSemaphore& image_acquired_semaphore = wd->Frames[wd->FrameIndex].ImageAcquiredSemaphore; VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore;
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex); err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
check_vk_result(err); check_vk_result(err);
ImGui_ImplVulkanH_FrameData* fd = &wd->Frames[wd->FrameIndex]; ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex];
{ {
err = vkWaitForFences(g_Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX); // wait indefinitely instead of periodically checking err = vkWaitForFences(g_Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX); // wait indefinitely instead of periodically checking
check_vk_result(err); check_vk_result(err);
@ -250,7 +269,7 @@ static void FrameRender(ImGui_ImplVulkanH_WindowData* wd)
VkRenderPassBeginInfo info = {}; VkRenderPassBeginInfo info = {};
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
info.renderPass = wd->RenderPass; info.renderPass = wd->RenderPass;
info.framebuffer = wd->Framebuffer[wd->FrameIndex]; info.framebuffer = fd->Framebuffer;
info.renderArea.extent.width = wd->Width; info.renderArea.extent.width = wd->Width;
info.renderArea.extent.height = wd->Height; info.renderArea.extent.height = wd->Height;
info.clearValueCount = 1; info.clearValueCount = 1;
@ -273,7 +292,7 @@ static void FrameRender(ImGui_ImplVulkanH_WindowData* wd)
info.commandBufferCount = 1; info.commandBufferCount = 1;
info.pCommandBuffers = &fd->CommandBuffer; info.pCommandBuffers = &fd->CommandBuffer;
info.signalSemaphoreCount = 1; info.signalSemaphoreCount = 1;
info.pSignalSemaphores = &fd->RenderCompleteSemaphore; info.pSignalSemaphores = &render_complete_semaphore;
err = vkEndCommandBuffer(fd->CommandBuffer); err = vkEndCommandBuffer(fd->CommandBuffer);
check_vk_result(err); check_vk_result(err);
@ -282,33 +301,33 @@ static void FrameRender(ImGui_ImplVulkanH_WindowData* wd)
} }
} }
static void FramePresent(ImGui_ImplVulkanH_WindowData* wd) static void FramePresent(ImGui_ImplVulkanH_Window* wd)
{ {
ImGui_ImplVulkanH_FrameData* fd = &wd->Frames[wd->FrameIndex]; VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
VkPresentInfoKHR info = {}; VkPresentInfoKHR info = {};
info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
info.waitSemaphoreCount = 1; info.waitSemaphoreCount = 1;
info.pWaitSemaphores = &fd->RenderCompleteSemaphore; info.pWaitSemaphores = &render_complete_semaphore;
info.swapchainCount = 1; info.swapchainCount = 1;
info.pSwapchains = &wd->Swapchain; info.pSwapchains = &wd->Swapchain;
info.pImageIndices = &wd->FrameIndex; info.pImageIndices = &wd->FrameIndex;
VkResult err = vkQueuePresentKHR(g_Queue, &info); VkResult err = vkQueuePresentKHR(g_Queue, &info);
check_vk_result(err); check_vk_result(err);
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->ImageCount; // Now we can use the next set of semaphores
} }
int main(int, char**) int main(int, char**)
{ {
// Setup SDL // Setup SDL
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0) if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
{ {
printf("Error: %s\n", SDL_GetError()); printf("Error: %s\n", SDL_GetError());
return 1; return 1;
} }
// Setup window // Setup window
SDL_DisplayMode current; SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
SDL_GetCurrentDisplayMode(0, &current); SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+Vulkan example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+Vulkan example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_VULKAN|SDL_WINDOW_RESIZABLE);
// Setup Vulkan // Setup Vulkan
uint32_t extensions_count = 0; uint32_t extensions_count = 0;
@ -330,13 +349,14 @@ int main(int, char**)
// Create Framebuffers // Create Framebuffers
int w, h; int w, h;
SDL_GetWindowSize(window, &w, &h); SDL_GetWindowSize(window, &w, &h);
ImGui_ImplVulkanH_WindowData* wd = &g_WindowData; ImGui_ImplVulkanH_Window* wd = &g_MainWindowData;
SetupVulkanWindowData(wd, surface, w, h); SetupVulkanWindow(wd, surface, w, h);
// Setup Dear ImGui context // Setup Dear ImGui context
ImGui::CreateContext(); ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io; ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
// Setup Dear ImGui style // Setup Dear ImGui style
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
@ -353,6 +373,8 @@ int main(int, char**)
init_info.PipelineCache = g_PipelineCache; init_info.PipelineCache = g_PipelineCache;
init_info.DescriptorPool = g_DescriptorPool; init_info.DescriptorPool = g_DescriptorPool;
init_info.Allocator = g_Allocator; init_info.Allocator = g_Allocator;
init_info.MinImageCount = g_MinImageCount;
init_info.ImageCount = wd->ImageCount;
init_info.CheckVkResultFn = check_vk_result; init_info.CheckVkResultFn = check_vk_result;
ImGui_ImplVulkan_Init(&init_info, wd->RenderPass); ImGui_ImplVulkan_Init(&init_info, wd->RenderPass);
@ -398,7 +420,7 @@ int main(int, char**)
err = vkDeviceWaitIdle(g_Device); err = vkDeviceWaitIdle(g_Device);
check_vk_result(err); check_vk_result(err);
ImGui_ImplVulkan_InvalidateFontUploadObjects(); ImGui_ImplVulkan_DestroyFontUploadObjects();
} }
bool show_demo_window = true; bool show_demo_window = true;
@ -421,7 +443,19 @@ int main(int, char**)
if (event.type == SDL_QUIT) if (event.type == SDL_QUIT)
done = true; done = true;
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED && event.window.windowID == SDL_GetWindowID(window)) if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED && event.window.windowID == SDL_GetWindowID(window))
ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(g_PhysicalDevice, g_Device, &g_WindowData, g_Allocator, (int)event.window.data1, (int)event.window.data2); {
g_SwapChainResizeWidth = (int)event.window.data1;
g_SwapChainResizeHeight = (int)event.window.data2;
g_SwapChainRebuild = true;
}
}
if (g_SwapChainRebuild)
{
g_SwapChainRebuild = false;
ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount);
ImGui_ImplVulkanH_CreateWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, g_SwapChainResizeWidth, g_SwapChainResizeHeight, g_MinImageCount);
g_MainWindowData.FrameIndex = 0;
} }
// Start the Dear ImGui frame // Start the Dear ImGui frame
@ -480,6 +514,8 @@ int main(int, char**)
ImGui_ImplVulkan_Shutdown(); ImGui_ImplVulkan_Shutdown();
ImGui_ImplSDL2_Shutdown(); ImGui_ImplSDL2_Shutdown();
ImGui::DestroyContext(); ImGui::DestroyContext();
CleanupVulkanWindow();
CleanupVulkan(); CleanupVulkan();
SDL_DestroyWindow(window); SDL_DestroyWindow(window);

View File

@ -21,29 +21,34 @@
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{345A953E-A004-4648-B442-DC5F9F11068C}</ProjectGuid> <ProjectGuid>{345A953E-A004-4648-B442-DC5F9F11068C}</ProjectGuid>
<RootNamespace>example_win32_directx10</RootNamespace> <RootNamespace>example_win32_directx10</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">
@ -81,7 +86,7 @@
<ClCompile> <ClCompile>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..;..;%(AdditionalIncludeDirectories);$(DXSDK_DIR)Include;</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
@ -94,7 +99,7 @@
<ClCompile> <ClCompile>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..;..;%(AdditionalIncludeDirectories);$(DXSDK_DIR)Include;</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
@ -109,7 +114,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..;..;%(AdditionalIncludeDirectories);$(DXSDK_DIR)Include;</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
</ClCompile> </ClCompile>
<Link> <Link>
@ -127,7 +132,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..;..;%(AdditionalIncludeDirectories);$(DXSDK_DIR)Include;</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
</ClCompile> </ClCompile>
<Link> <Link>

View File

@ -15,106 +15,39 @@ static ID3D10Device* g_pd3dDevice = NULL;
static IDXGISwapChain* g_pSwapChain = NULL; static IDXGISwapChain* g_pSwapChain = NULL;
static ID3D10RenderTargetView* g_mainRenderTargetView = NULL; static ID3D10RenderTargetView* g_mainRenderTargetView = NULL;
void CreateRenderTarget() // Forward declarations of helper functions
{ bool CreateDeviceD3D(HWND hWnd);
ID3D10Texture2D* pBackBuffer; void CleanupDeviceD3D();
g_pSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*)&pBackBuffer); void CreateRenderTarget();
g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_mainRenderTargetView); void CleanupRenderTarget();
pBackBuffer->Release(); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
}
void CleanupRenderTarget()
{
if (g_mainRenderTargetView) { g_mainRenderTargetView->Release(); g_mainRenderTargetView = NULL; }
}
HRESULT CreateDeviceD3D(HWND hWnd)
{
// Setup swap chain
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = 2;
sd.BufferDesc.Width = 0;
sd.BufferDesc.Height = 0;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = hWnd;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = TRUE;
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
UINT createDeviceFlags = 0;
//createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG;
if (D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice) != S_OK)
return E_FAIL;
CreateRenderTarget();
return S_OK;
}
void CleanupDeviceD3D()
{
CleanupRenderTarget();
if (g_pSwapChain) { g_pSwapChain->Release(); g_pSwapChain = NULL; }
if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; }
}
extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
return true;
switch (msg)
{
case WM_SIZE:
if (g_pd3dDevice != NULL && wParam != SIZE_MINIMIZED)
{
CleanupRenderTarget();
g_pSwapChain->ResizeBuffers(0, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam), DXGI_FORMAT_UNKNOWN, 0);
CreateRenderTarget();
}
return 0;
case WM_SYSCOMMAND:
if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu
return 0;
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
// Main code
int main(int, char**) int main(int, char**)
{ {
// Create application window // Create application window
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, _T("ImGui Example"), NULL }; WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, _T("ImGui Example"), NULL };
RegisterClassEx(&wc); ::RegisterClassEx(&wc);
HWND hwnd = CreateWindow(_T("ImGui Example"), _T("Dear ImGui DirectX10 Example"), WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL); HWND hwnd = ::CreateWindow(wc.lpszClassName, _T("Dear ImGui DirectX10 Example"), WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
// Initialize Direct3D // Initialize Direct3D
if (CreateDeviceD3D(hwnd) < 0) if (!CreateDeviceD3D(hwnd))
{ {
CleanupDeviceD3D(); CleanupDeviceD3D();
UnregisterClass(_T("ImGui Example"), wc.hInstance); ::UnregisterClass(wc.lpszClassName, wc.hInstance);
return 1; return 1;
} }
// Show the window // Show the window
ShowWindow(hwnd, SW_SHOWDEFAULT); ::ShowWindow(hwnd, SW_SHOWDEFAULT);
UpdateWindow(hwnd); ::UpdateWindow(hwnd);
// Setup Dear ImGui context // Setup Dear ImGui context
IMGUI_CHECKVERSION(); IMGUI_CHECKVERSION();
ImGui::CreateContext(); ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io; ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
// Setup Dear ImGui style // Setup Dear ImGui style
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
@ -139,6 +72,7 @@ int main(int, char**)
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese());
//IM_ASSERT(font != NULL); //IM_ASSERT(font != NULL);
// Our state
bool show_demo_window = true; bool show_demo_window = true;
bool show_another_window = false; bool show_another_window = false;
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
@ -153,10 +87,10 @@ int main(int, char**)
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) if (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{ {
TranslateMessage(&msg); ::TranslateMessage(&msg);
DispatchMessage(&msg); ::DispatchMessage(&msg);
continue; continue;
} }
@ -217,8 +151,86 @@ int main(int, char**)
ImGui::DestroyContext(); ImGui::DestroyContext();
CleanupDeviceD3D(); CleanupDeviceD3D();
DestroyWindow(hwnd); ::DestroyWindow(hwnd);
UnregisterClass(_T("ImGui Example"), wc.hInstance); ::UnregisterClass(wc.lpszClassName, wc.hInstance);
return 0; return 0;
} }
// Helper functions
bool CreateDeviceD3D(HWND hWnd)
{
// Setup swap chain
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = 2;
sd.BufferDesc.Width = 0;
sd.BufferDesc.Height = 0;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = hWnd;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = TRUE;
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
UINT createDeviceFlags = 0;
//createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG;
if (D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice) != S_OK)
return false;
CreateRenderTarget();
return true;
}
void CleanupDeviceD3D()
{
CleanupRenderTarget();
if (g_pSwapChain) { g_pSwapChain->Release(); g_pSwapChain = NULL; }
if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; }
}
void CreateRenderTarget()
{
ID3D10Texture2D* pBackBuffer;
g_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_mainRenderTargetView);
pBackBuffer->Release();
}
void CleanupRenderTarget()
{
if (g_mainRenderTargetView) { g_mainRenderTargetView->Release(); g_mainRenderTargetView = NULL; }
}
// Win32 message handler
extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
return true;
switch (msg)
{
case WM_SIZE:
if (g_pd3dDevice != NULL && wParam != SIZE_MINIMIZED)
{
CleanupRenderTarget();
g_pSwapChain->ResizeBuffers(0, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam), DXGI_FORMAT_UNKNOWN, 0);
CreateRenderTarget();
}
return 0;
case WM_SYSCOMMAND:
if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu
return 0;
break;
case WM_DESTROY:
::PostQuitMessage(0);
return 0;
}
return ::DefWindowProc(hWnd, msg, wParam, lParam);
}

View File

@ -27,23 +27,27 @@
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">
@ -81,7 +85,7 @@
<ClCompile> <ClCompile>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..;..;%(AdditionalIncludeDirectories);$(DXSDK_DIR)Include;</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
@ -94,7 +98,7 @@
<ClCompile> <ClCompile>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..;..;%(AdditionalIncludeDirectories);$(DXSDK_DIR)Include;</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
@ -109,7 +113,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..;..;%(AdditionalIncludeDirectories);$(DXSDK_DIR)Include;</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
</ClCompile> </ClCompile>
<Link> <Link>
@ -127,7 +131,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..;..;%(AdditionalIncludeDirectories);$(DXSDK_DIR)Include;</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
</ClCompile> </ClCompile>
<Link> <Link>

View File

@ -15,109 +15,39 @@ static ID3D11DeviceContext* g_pd3dDeviceContext = NULL;
static IDXGISwapChain* g_pSwapChain = NULL; static IDXGISwapChain* g_pSwapChain = NULL;
static ID3D11RenderTargetView* g_mainRenderTargetView = NULL; static ID3D11RenderTargetView* g_mainRenderTargetView = NULL;
void CreateRenderTarget() // Forward declarations of helper functions
{ bool CreateDeviceD3D(HWND hWnd);
ID3D11Texture2D* pBackBuffer; void CleanupDeviceD3D();
g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer); void CreateRenderTarget();
g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_mainRenderTargetView); void CleanupRenderTarget();
pBackBuffer->Release(); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
}
void CleanupRenderTarget()
{
if (g_mainRenderTargetView) { g_mainRenderTargetView->Release(); g_mainRenderTargetView = NULL; }
}
HRESULT CreateDeviceD3D(HWND hWnd)
{
// Setup swap chain
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = 2;
sd.BufferDesc.Width = 0;
sd.BufferDesc.Height = 0;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = hWnd;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = TRUE;
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
UINT createDeviceFlags = 0;
//createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
D3D_FEATURE_LEVEL featureLevel;
const D3D_FEATURE_LEVEL featureLevelArray[2] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, };
if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK)
return E_FAIL;
CreateRenderTarget();
return S_OK;
}
void CleanupDeviceD3D()
{
CleanupRenderTarget();
if (g_pSwapChain) { g_pSwapChain->Release(); g_pSwapChain = NULL; }
if (g_pd3dDeviceContext) { g_pd3dDeviceContext->Release(); g_pd3dDeviceContext = NULL; }
if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; }
}
extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
return true;
switch (msg)
{
case WM_SIZE:
if (g_pd3dDevice != NULL && wParam != SIZE_MINIMIZED)
{
CleanupRenderTarget();
g_pSwapChain->ResizeBuffers(0, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam), DXGI_FORMAT_UNKNOWN, 0);
CreateRenderTarget();
}
return 0;
case WM_SYSCOMMAND:
if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu
return 0;
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
// Main code
int main(int, char**) int main(int, char**)
{ {
// Create application window // Create application window
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, _T("ImGui Example"), NULL }; WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, _T("ImGui Example"), NULL };
RegisterClassEx(&wc); ::RegisterClassEx(&wc);
HWND hwnd = CreateWindow(_T("ImGui Example"), _T("Dear ImGui DirectX11 Example"), WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL); HWND hwnd = ::CreateWindow(wc.lpszClassName, _T("Dear ImGui DirectX11 Example"), WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
// Initialize Direct3D // Initialize Direct3D
if (CreateDeviceD3D(hwnd) < 0) if (!CreateDeviceD3D(hwnd))
{ {
CleanupDeviceD3D(); CleanupDeviceD3D();
UnregisterClass(_T("ImGui Example"), wc.hInstance); ::UnregisterClass(wc.lpszClassName, wc.hInstance);
return 1; return 1;
} }
// Show the window // Show the window
ShowWindow(hwnd, SW_SHOWDEFAULT); ::ShowWindow(hwnd, SW_SHOWDEFAULT);
UpdateWindow(hwnd); ::UpdateWindow(hwnd);
// Setup Dear ImGui context // Setup Dear ImGui context
IMGUI_CHECKVERSION(); IMGUI_CHECKVERSION();
ImGui::CreateContext(); ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io; ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
// Setup Dear ImGui style // Setup Dear ImGui style
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
@ -157,10 +87,10 @@ int main(int, char**)
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) if (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{ {
TranslateMessage(&msg); ::TranslateMessage(&msg);
DispatchMessage(&msg); ::DispatchMessage(&msg);
continue; continue;
} }
@ -221,8 +151,89 @@ int main(int, char**)
ImGui::DestroyContext(); ImGui::DestroyContext();
CleanupDeviceD3D(); CleanupDeviceD3D();
DestroyWindow(hwnd); ::DestroyWindow(hwnd);
UnregisterClass(_T("ImGui Example"), wc.hInstance); ::UnregisterClass(wc.lpszClassName, wc.hInstance);
return 0; return 0;
} }
// Helper functions
bool CreateDeviceD3D(HWND hWnd)
{
// Setup swap chain
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = 2;
sd.BufferDesc.Width = 0;
sd.BufferDesc.Height = 0;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = hWnd;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = TRUE;
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
UINT createDeviceFlags = 0;
//createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
D3D_FEATURE_LEVEL featureLevel;
const D3D_FEATURE_LEVEL featureLevelArray[2] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, };
if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK)
return false;
CreateRenderTarget();
return true;
}
void CleanupDeviceD3D()
{
CleanupRenderTarget();
if (g_pSwapChain) { g_pSwapChain->Release(); g_pSwapChain = NULL; }
if (g_pd3dDeviceContext) { g_pd3dDeviceContext->Release(); g_pd3dDeviceContext = NULL; }
if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; }
}
void CreateRenderTarget()
{
ID3D11Texture2D* pBackBuffer;
g_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_mainRenderTargetView);
pBackBuffer->Release();
}
void CleanupRenderTarget()
{
if (g_mainRenderTargetView) { g_mainRenderTargetView->Release(); g_mainRenderTargetView = NULL; }
}
// Win32 message handler
extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
return true;
switch (msg)
{
case WM_SIZE:
if (g_pd3dDevice != NULL && wParam != SIZE_MINIMIZED)
{
CleanupRenderTarget();
g_pSwapChain->ResizeBuffers(0, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam), DXGI_FORMAT_UNKNOWN, 0);
CreateRenderTarget();
}
return 0;
case WM_SYSCOMMAND:
if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu
return 0;
break;
case WM_DESTROY:
::PostQuitMessage(0);
return 0;
}
return ::DefWindowProc(hWnd, msg, wParam, lParam);
}

View File

@ -21,7 +21,7 @@
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{b4cf9797-519d-4afe-a8f4-5141a6b521d3}</ProjectGuid> <ProjectGuid>{b4cf9797-519d-4afe-a8f4-5141a6b521d3}</ProjectGuid>
<RootNamespace>example_win32_directx12</RootNamespace> <RootNamespace>example_win32_directx12</RootNamespace>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

View File

@ -36,261 +36,42 @@ static HANDLE g_hSwapChainWaitableObject = NULL;
static ID3D12Resource* g_mainRenderTargetResource[NUM_BACK_BUFFERS] = {}; static ID3D12Resource* g_mainRenderTargetResource[NUM_BACK_BUFFERS] = {};
static D3D12_CPU_DESCRIPTOR_HANDLE g_mainRenderTargetDescriptor[NUM_BACK_BUFFERS] = {}; static D3D12_CPU_DESCRIPTOR_HANDLE g_mainRenderTargetDescriptor[NUM_BACK_BUFFERS] = {};
void CreateRenderTarget() // Forward declarations of helper functions
{ bool CreateDeviceD3D(HWND hWnd);
ID3D12Resource* pBackBuffer; void CleanupDeviceD3D();
for (UINT i = 0; i < NUM_BACK_BUFFERS; i++) void CreateRenderTarget();
{ void CleanupRenderTarget();
g_pSwapChain->GetBuffer(i, IID_PPV_ARGS(&pBackBuffer)); void WaitForLastSubmittedFrame();
g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, g_mainRenderTargetDescriptor[i]); FrameContext* WaitForNextFrameResources();
g_mainRenderTargetResource[i] = pBackBuffer; void ResizeSwapChain(HWND hWnd, int width, int height);
} LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
}
void WaitForLastSubmittedFrame()
{
FrameContext* frameCtxt = &g_frameContext[g_frameIndex % NUM_FRAMES_IN_FLIGHT];
UINT64 fenceValue = frameCtxt->FenceValue;
if (fenceValue == 0)
return; // No fence was signaled
frameCtxt->FenceValue = 0;
if (g_fence->GetCompletedValue() >= fenceValue)
return;
g_fence->SetEventOnCompletion(fenceValue, g_fenceEvent);
WaitForSingleObject(g_fenceEvent, INFINITE);
}
FrameContext* WaitForNextFrameResources()
{
UINT nextFrameIndex = g_frameIndex + 1;
g_frameIndex = nextFrameIndex;
HANDLE waitableObjects[] = { g_hSwapChainWaitableObject, NULL };
DWORD numWaitableObjects = 1;
FrameContext* frameCtxt = &g_frameContext[nextFrameIndex % NUM_FRAMES_IN_FLIGHT];
UINT64 fenceValue = frameCtxt->FenceValue;
if (fenceValue != 0) // means no fence was signaled
{
frameCtxt->FenceValue = 0;
g_fence->SetEventOnCompletion(fenceValue, g_fenceEvent);
waitableObjects[1] = g_fenceEvent;
numWaitableObjects = 2;
}
WaitForMultipleObjects(numWaitableObjects, waitableObjects, TRUE, INFINITE);
return frameCtxt;
}
void ResizeSwapChain(HWND hWnd, int width, int height)
{
DXGI_SWAP_CHAIN_DESC1 sd;
g_pSwapChain->GetDesc1(&sd);
sd.Width = width;
sd.Height = height;
IDXGIFactory4* dxgiFactory = NULL;
g_pSwapChain->GetParent(IID_PPV_ARGS(&dxgiFactory));
g_pSwapChain->Release();
CloseHandle(g_hSwapChainWaitableObject);
IDXGISwapChain1* swapChain1 = NULL;
dxgiFactory->CreateSwapChainForHwnd(g_pd3dCommandQueue, hWnd, &sd, NULL, NULL, &swapChain1);
swapChain1->QueryInterface(IID_PPV_ARGS(&g_pSwapChain));
swapChain1->Release();
dxgiFactory->Release();
g_pSwapChain->SetMaximumFrameLatency(NUM_BACK_BUFFERS);
g_hSwapChainWaitableObject = g_pSwapChain->GetFrameLatencyWaitableObject();
assert(g_hSwapChainWaitableObject != NULL);
}
void CleanupRenderTarget()
{
WaitForLastSubmittedFrame();
for (UINT i = 0; i < NUM_BACK_BUFFERS; i++)
if (g_mainRenderTargetResource[i]) { g_mainRenderTargetResource[i]->Release(); g_mainRenderTargetResource[i] = NULL; }
}
HRESULT CreateDeviceD3D(HWND hWnd)
{
// Setup swap chain
DXGI_SWAP_CHAIN_DESC1 sd;
{
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = NUM_BACK_BUFFERS;
sd.Width = 0;
sd.Height = 0;
sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
sd.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
sd.Scaling = DXGI_SCALING_STRETCH;
sd.Stereo = FALSE;
}
if (DX12_ENABLE_DEBUG_LAYER)
{
ID3D12Debug* dx12Debug = NULL;
if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&dx12Debug))))
{
dx12Debug->EnableDebugLayer();
dx12Debug->Release();
}
}
D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0;
if (D3D12CreateDevice(NULL, featureLevel, IID_PPV_ARGS(&g_pd3dDevice)) != S_OK)
return E_FAIL;
{
D3D12_DESCRIPTOR_HEAP_DESC desc = {};
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
desc.NumDescriptors = NUM_BACK_BUFFERS;
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
desc.NodeMask = 1;
if (g_pd3dDevice->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&g_pd3dRtvDescHeap)) != S_OK)
return E_FAIL;
SIZE_T rtvDescriptorSize = g_pd3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = g_pd3dRtvDescHeap->GetCPUDescriptorHandleForHeapStart();
for (UINT i = 0; i < NUM_BACK_BUFFERS; i++)
{
g_mainRenderTargetDescriptor[i] = rtvHandle;
rtvHandle.ptr += rtvDescriptorSize;
}
}
{
D3D12_DESCRIPTOR_HEAP_DESC desc = {};
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
desc.NumDescriptors = 1;
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
if (g_pd3dDevice->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&g_pd3dSrvDescHeap)) != S_OK)
return E_FAIL;
}
{
D3D12_COMMAND_QUEUE_DESC desc = {};
desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
desc.NodeMask = 1;
if (g_pd3dDevice->CreateCommandQueue(&desc, IID_PPV_ARGS(&g_pd3dCommandQueue)) != S_OK)
return E_FAIL;
}
for (UINT i = 0; i < NUM_FRAMES_IN_FLIGHT; i++)
if (g_pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&g_frameContext[i].CommandAllocator)) != S_OK)
return E_FAIL;
if (g_pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, g_frameContext[0].CommandAllocator, NULL, IID_PPV_ARGS(&g_pd3dCommandList)) != S_OK ||
g_pd3dCommandList->Close() != S_OK)
return E_FAIL;
if (g_pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&g_fence)) != S_OK)
return E_FAIL;
g_fenceEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (g_fenceEvent == NULL)
return E_FAIL;
{
IDXGIFactory4* dxgiFactory = NULL;
IDXGISwapChain1* swapChain1 = NULL;
if (CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory)) != S_OK ||
dxgiFactory->CreateSwapChainForHwnd(g_pd3dCommandQueue, hWnd, &sd, NULL, NULL, &swapChain1) != S_OK ||
swapChain1->QueryInterface(IID_PPV_ARGS(&g_pSwapChain)) != S_OK)
return E_FAIL;
swapChain1->Release();
dxgiFactory->Release();
g_pSwapChain->SetMaximumFrameLatency(NUM_BACK_BUFFERS);
g_hSwapChainWaitableObject = g_pSwapChain->GetFrameLatencyWaitableObject();
}
CreateRenderTarget();
return S_OK;
}
void CleanupDeviceD3D()
{
CleanupRenderTarget();
if (g_pSwapChain) { g_pSwapChain->Release(); g_pSwapChain = NULL; }
if (g_hSwapChainWaitableObject != NULL) { CloseHandle(g_hSwapChainWaitableObject); }
for (UINT i = 0; i < NUM_FRAMES_IN_FLIGHT; i++)
if (g_frameContext[i].CommandAllocator) { g_frameContext[i].CommandAllocator->Release(); g_frameContext[i].CommandAllocator = NULL; }
if (g_pd3dCommandQueue) { g_pd3dCommandQueue->Release(); g_pd3dCommandQueue = NULL; }
if (g_pd3dCommandList) { g_pd3dCommandList->Release(); g_pd3dCommandList = NULL; }
if (g_pd3dRtvDescHeap) { g_pd3dRtvDescHeap->Release(); g_pd3dRtvDescHeap = NULL; }
if (g_pd3dSrvDescHeap) { g_pd3dSrvDescHeap->Release(); g_pd3dSrvDescHeap = NULL; }
if (g_fence) { g_fence->Release(); g_fence = NULL; }
if (g_fenceEvent) { CloseHandle(g_fenceEvent); g_fenceEvent = NULL; }
if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; }
}
extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
return true;
switch (msg)
{
case WM_SIZE:
if (g_pd3dDevice != NULL && wParam != SIZE_MINIMIZED)
{
ImGui_ImplDX12_InvalidateDeviceObjects();
CleanupRenderTarget();
ResizeSwapChain(hWnd, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam));
CreateRenderTarget();
ImGui_ImplDX12_CreateDeviceObjects();
}
return 0;
case WM_SYSCOMMAND:
if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu
return 0;
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
// Main code
int main(int, char**) int main(int, char**)
{ {
// Create application window // Create application window
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, _T("ImGui Example"), NULL }; WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, _T("ImGui Example"), NULL };
RegisterClassEx(&wc); ::RegisterClassEx(&wc);
HWND hwnd = CreateWindow(_T("ImGui Example"), _T("Dear ImGui DirectX12 Example"), WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL); HWND hwnd = ::CreateWindow(wc.lpszClassName, _T("Dear ImGui DirectX12 Example"), WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
// Initialize Direct3D // Initialize Direct3D
if (CreateDeviceD3D(hwnd) < 0) if (!CreateDeviceD3D(hwnd))
{ {
CleanupDeviceD3D(); CleanupDeviceD3D();
UnregisterClass(_T("ImGui Example"), wc.hInstance); ::UnregisterClass(wc.lpszClassName, wc.hInstance);
return 1; return 1;
} }
// Show the window // Show the window
ShowWindow(hwnd, SW_SHOWDEFAULT); ::ShowWindow(hwnd, SW_SHOWDEFAULT);
UpdateWindow(hwnd); ::UpdateWindow(hwnd);
// Setup Dear ImGui context // Setup Dear ImGui context
IMGUI_CHECKVERSION(); IMGUI_CHECKVERSION();
ImGui::CreateContext(); ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io; ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
// Setup Dear ImGui style // Setup Dear ImGui style
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
@ -318,6 +99,7 @@ int main(int, char**)
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese());
//IM_ASSERT(font != NULL); //IM_ASSERT(font != NULL);
// Our state
bool show_demo_window = true; bool show_demo_window = true;
bool show_another_window = false; bool show_another_window = false;
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
@ -332,10 +114,10 @@ int main(int, char**)
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) if (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{ {
TranslateMessage(&msg); ::TranslateMessage(&msg);
DispatchMessage(&msg); ::DispatchMessage(&msg);
continue; continue;
} }
@ -423,8 +205,241 @@ int main(int, char**)
ImGui::DestroyContext(); ImGui::DestroyContext();
CleanupDeviceD3D(); CleanupDeviceD3D();
DestroyWindow(hwnd); ::DestroyWindow(hwnd);
UnregisterClass(_T("ImGui Example"), wc.hInstance); ::UnregisterClass(wc.lpszClassName, wc.hInstance);
return 0; return 0;
} }
// Helper functions
bool CreateDeviceD3D(HWND hWnd)
{
// Setup swap chain
DXGI_SWAP_CHAIN_DESC1 sd;
{
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = NUM_BACK_BUFFERS;
sd.Width = 0;
sd.Height = 0;
sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
sd.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
sd.Scaling = DXGI_SCALING_STRETCH;
sd.Stereo = FALSE;
}
if (DX12_ENABLE_DEBUG_LAYER)
{
ID3D12Debug* dx12Debug = NULL;
if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&dx12Debug))))
{
dx12Debug->EnableDebugLayer();
dx12Debug->Release();
}
}
D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0;
if (D3D12CreateDevice(NULL, featureLevel, IID_PPV_ARGS(&g_pd3dDevice)) != S_OK)
return false;
{
D3D12_DESCRIPTOR_HEAP_DESC desc = {};
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
desc.NumDescriptors = NUM_BACK_BUFFERS;
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
desc.NodeMask = 1;
if (g_pd3dDevice->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&g_pd3dRtvDescHeap)) != S_OK)
return false;
SIZE_T rtvDescriptorSize = g_pd3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = g_pd3dRtvDescHeap->GetCPUDescriptorHandleForHeapStart();
for (UINT i = 0; i < NUM_BACK_BUFFERS; i++)
{
g_mainRenderTargetDescriptor[i] = rtvHandle;
rtvHandle.ptr += rtvDescriptorSize;
}
}
{
D3D12_DESCRIPTOR_HEAP_DESC desc = {};
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
desc.NumDescriptors = 1;
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
if (g_pd3dDevice->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&g_pd3dSrvDescHeap)) != S_OK)
return false;
}
{
D3D12_COMMAND_QUEUE_DESC desc = {};
desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
desc.NodeMask = 1;
if (g_pd3dDevice->CreateCommandQueue(&desc, IID_PPV_ARGS(&g_pd3dCommandQueue)) != S_OK)
return false;
}
for (UINT i = 0; i < NUM_FRAMES_IN_FLIGHT; i++)
if (g_pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&g_frameContext[i].CommandAllocator)) != S_OK)
return false;
if (g_pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, g_frameContext[0].CommandAllocator, NULL, IID_PPV_ARGS(&g_pd3dCommandList)) != S_OK ||
g_pd3dCommandList->Close() != S_OK)
return false;
if (g_pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&g_fence)) != S_OK)
return false;
g_fenceEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (g_fenceEvent == NULL)
return false;
{
IDXGIFactory4* dxgiFactory = NULL;
IDXGISwapChain1* swapChain1 = NULL;
if (CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory)) != S_OK ||
dxgiFactory->CreateSwapChainForHwnd(g_pd3dCommandQueue, hWnd, &sd, NULL, NULL, &swapChain1) != S_OK ||
swapChain1->QueryInterface(IID_PPV_ARGS(&g_pSwapChain)) != S_OK)
return false;
swapChain1->Release();
dxgiFactory->Release();
g_pSwapChain->SetMaximumFrameLatency(NUM_BACK_BUFFERS);
g_hSwapChainWaitableObject = g_pSwapChain->GetFrameLatencyWaitableObject();
}
CreateRenderTarget();
return true;
}
void CleanupDeviceD3D()
{
CleanupRenderTarget();
if (g_pSwapChain) { g_pSwapChain->Release(); g_pSwapChain = NULL; }
if (g_hSwapChainWaitableObject != NULL) { CloseHandle(g_hSwapChainWaitableObject); }
for (UINT i = 0; i < NUM_FRAMES_IN_FLIGHT; i++)
if (g_frameContext[i].CommandAllocator) { g_frameContext[i].CommandAllocator->Release(); g_frameContext[i].CommandAllocator = NULL; }
if (g_pd3dCommandQueue) { g_pd3dCommandQueue->Release(); g_pd3dCommandQueue = NULL; }
if (g_pd3dCommandList) { g_pd3dCommandList->Release(); g_pd3dCommandList = NULL; }
if (g_pd3dRtvDescHeap) { g_pd3dRtvDescHeap->Release(); g_pd3dRtvDescHeap = NULL; }
if (g_pd3dSrvDescHeap) { g_pd3dSrvDescHeap->Release(); g_pd3dSrvDescHeap = NULL; }
if (g_fence) { g_fence->Release(); g_fence = NULL; }
if (g_fenceEvent) { CloseHandle(g_fenceEvent); g_fenceEvent = NULL; }
if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; }
}
void CreateRenderTarget()
{
for (UINT i = 0; i < NUM_BACK_BUFFERS; i++)
{
ID3D12Resource* pBackBuffer = NULL;
g_pSwapChain->GetBuffer(i, IID_PPV_ARGS(&pBackBuffer));
g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, g_mainRenderTargetDescriptor[i]);
g_mainRenderTargetResource[i] = pBackBuffer;
}
}
void CleanupRenderTarget()
{
WaitForLastSubmittedFrame();
for (UINT i = 0; i < NUM_BACK_BUFFERS; i++)
if (g_mainRenderTargetResource[i]) { g_mainRenderTargetResource[i]->Release(); g_mainRenderTargetResource[i] = NULL; }
}
void WaitForLastSubmittedFrame()
{
FrameContext* frameCtxt = &g_frameContext[g_frameIndex % NUM_FRAMES_IN_FLIGHT];
UINT64 fenceValue = frameCtxt->FenceValue;
if (fenceValue == 0)
return; // No fence was signaled
frameCtxt->FenceValue = 0;
if (g_fence->GetCompletedValue() >= fenceValue)
return;
g_fence->SetEventOnCompletion(fenceValue, g_fenceEvent);
WaitForSingleObject(g_fenceEvent, INFINITE);
}
FrameContext* WaitForNextFrameResources()
{
UINT nextFrameIndex = g_frameIndex + 1;
g_frameIndex = nextFrameIndex;
HANDLE waitableObjects[] = { g_hSwapChainWaitableObject, NULL };
DWORD numWaitableObjects = 1;
FrameContext* frameCtxt = &g_frameContext[nextFrameIndex % NUM_FRAMES_IN_FLIGHT];
UINT64 fenceValue = frameCtxt->FenceValue;
if (fenceValue != 0) // means no fence was signaled
{
frameCtxt->FenceValue = 0;
g_fence->SetEventOnCompletion(fenceValue, g_fenceEvent);
waitableObjects[1] = g_fenceEvent;
numWaitableObjects = 2;
}
WaitForMultipleObjects(numWaitableObjects, waitableObjects, TRUE, INFINITE);
return frameCtxt;
}
void ResizeSwapChain(HWND hWnd, int width, int height)
{
DXGI_SWAP_CHAIN_DESC1 sd;
g_pSwapChain->GetDesc1(&sd);
sd.Width = width;
sd.Height = height;
IDXGIFactory4* dxgiFactory = NULL;
g_pSwapChain->GetParent(IID_PPV_ARGS(&dxgiFactory));
g_pSwapChain->Release();
CloseHandle(g_hSwapChainWaitableObject);
IDXGISwapChain1* swapChain1 = NULL;
dxgiFactory->CreateSwapChainForHwnd(g_pd3dCommandQueue, hWnd, &sd, NULL, NULL, &swapChain1);
swapChain1->QueryInterface(IID_PPV_ARGS(&g_pSwapChain));
swapChain1->Release();
dxgiFactory->Release();
g_pSwapChain->SetMaximumFrameLatency(NUM_BACK_BUFFERS);
g_hSwapChainWaitableObject = g_pSwapChain->GetFrameLatencyWaitableObject();
assert(g_hSwapChainWaitableObject != NULL);
}
// Win32 message handler
extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
return true;
switch (msg)
{
case WM_SIZE:
if (g_pd3dDevice != NULL && wParam != SIZE_MINIMIZED)
{
ImGui_ImplDX12_InvalidateDeviceObjects();
CleanupRenderTarget();
ResizeSwapChain(hWnd, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam));
CreateRenderTarget();
ImGui_ImplDX12_CreateDeviceObjects();
}
return 0;
case WM_SYSCOMMAND:
if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu
return 0;
break;
case WM_DESTROY:
::PostQuitMessage(0);
return 0;
}
return ::DefWindowProc(hWnd, msg, wParam, lParam);
}

View File

@ -21,29 +21,34 @@
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{4165A294-21F2-44CA-9B38-E3F935ABADF5}</ProjectGuid> <ProjectGuid>{4165A294-21F2-44CA-9B38-E3F935ABADF5}</ProjectGuid>
<RootNamespace>example_win32_directx9</RootNamespace> <RootNamespace>example_win32_directx9</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">
@ -85,7 +90,7 @@
</ClCompile> </ClCompile>
<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;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>d3d9.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
</Link> </Link>
@ -98,7 +103,7 @@
</ClCompile> </ClCompile>
<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;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>d3d9.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
</Link> </Link>
@ -116,7 +121,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<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;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>d3d9.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
</Link> </Link>
@ -134,7 +139,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<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;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>d3d9.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
</Link> </Link>

View File

@ -10,76 +10,42 @@
#include <tchar.h> #include <tchar.h>
// Data // Data
static LPDIRECT3D9 g_pD3D = NULL;
static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;
static D3DPRESENT_PARAMETERS g_d3dpp; static D3DPRESENT_PARAMETERS g_d3dpp = {};
extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); // Forward declarations of helper functions
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) bool CreateDeviceD3D(HWND hWnd);
{ void CleanupDeviceD3D();
if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) void ResetDevice();
return true; LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
switch (msg)
{
case WM_SIZE:
if (g_pd3dDevice != NULL && wParam != SIZE_MINIMIZED)
{
ImGui_ImplDX9_InvalidateDeviceObjects();
g_d3dpp.BackBufferWidth = LOWORD(lParam);
g_d3dpp.BackBufferHeight = HIWORD(lParam);
HRESULT hr = g_pd3dDevice->Reset(&g_d3dpp);
if (hr == D3DERR_INVALIDCALL)
IM_ASSERT(0);
ImGui_ImplDX9_CreateDeviceObjects();
}
return 0;
case WM_SYSCOMMAND:
if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu
return 0;
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
// Main code
int main(int, char**) int main(int, char**)
{ {
// Create application window // Create application window
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, _T("ImGui Example"), NULL }; WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, _T("ImGui Example"), NULL };
RegisterClassEx(&wc); ::RegisterClassEx(&wc);
HWND hwnd = CreateWindow(_T("ImGui Example"), _T("Dear ImGui DirectX9 Example"), WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL); HWND hwnd = ::CreateWindow(wc.lpszClassName, _T("Dear ImGui DirectX9 Example"), WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
// Initialize Direct3D // Initialize Direct3D
LPDIRECT3D9 pD3D; if (!CreateDeviceD3D(hwnd))
if ((pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL)
{ {
UnregisterClass(_T("ImGui Example"), wc.hInstance); CleanupDeviceD3D();
return 0; ::UnregisterClass(wc.lpszClassName, wc.hInstance);
return 1;
} }
ZeroMemory(&g_d3dpp, sizeof(g_d3dpp));
g_d3dpp.Windowed = TRUE;
g_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
g_d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
g_d3dpp.EnableAutoDepthStencil = TRUE;
g_d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; // Present with vsync
//g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // Present without vsync, maximum unthrottled framerate
// Create the D3DDevice // Show the window
if (pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &g_d3dpp, &g_pd3dDevice) < 0) ::ShowWindow(hwnd, SW_SHOWDEFAULT);
{ ::UpdateWindow(hwnd);
pD3D->Release();
UnregisterClass(_T("ImGui Example"), wc.hInstance);
return 0;
}
// Setup Dear ImGui context // Setup Dear ImGui context
IMGUI_CHECKVERSION(); IMGUI_CHECKVERSION();
ImGui::CreateContext(); ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io; ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
// Setup Dear ImGui style // Setup Dear ImGui style
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
@ -104,6 +70,7 @@ int main(int, char**)
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese());
//IM_ASSERT(font != NULL); //IM_ASSERT(font != NULL);
// Our state
bool show_demo_window = true; bool show_demo_window = true;
bool show_another_window = false; bool show_another_window = false;
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
@ -111,8 +78,6 @@ int main(int, char**)
// Main loop // Main loop
MSG msg; MSG msg;
ZeroMemory(&msg, sizeof(msg)); ZeroMemory(&msg, sizeof(msg));
ShowWindow(hwnd, SW_SHOWDEFAULT);
UpdateWindow(hwnd);
while (msg.message != WM_QUIT) while (msg.message != WM_QUIT)
{ {
// Poll and handle messages (inputs, window resize, etc.) // Poll and handle messages (inputs, window resize, etc.)
@ -120,10 +85,10 @@ int main(int, char**)
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) if (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{ {
TranslateMessage(&msg); ::TranslateMessage(&msg);
DispatchMessage(&msg); ::DispatchMessage(&msg);
continue; continue;
} }
@ -186,21 +151,81 @@ int main(int, char**)
// Handle loss of D3D9 device // Handle loss of D3D9 device
if (result == D3DERR_DEVICELOST && g_pd3dDevice->TestCooperativeLevel() == D3DERR_DEVICENOTRESET) if (result == D3DERR_DEVICELOST && g_pd3dDevice->TestCooperativeLevel() == D3DERR_DEVICENOTRESET)
{ ResetDevice();
ImGui_ImplDX9_InvalidateDeviceObjects();
g_pd3dDevice->Reset(&g_d3dpp);
ImGui_ImplDX9_CreateDeviceObjects();
}
} }
ImGui_ImplDX9_Shutdown(); ImGui_ImplDX9_Shutdown();
ImGui_ImplWin32_Shutdown(); ImGui_ImplWin32_Shutdown();
ImGui::DestroyContext(); ImGui::DestroyContext();
if (g_pd3dDevice) g_pd3dDevice->Release(); CleanupDeviceD3D();
if (pD3D) pD3D->Release(); ::DestroyWindow(hwnd);
DestroyWindow(hwnd); ::UnregisterClass(wc.lpszClassName, wc.hInstance);
UnregisterClass(_T("ImGui Example"), wc.hInstance);
return 0; return 0;
} }
// Helper functions
bool CreateDeviceD3D(HWND hWnd)
{
if ((g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL)
return false;
// Create the D3DDevice
ZeroMemory(&g_d3dpp, sizeof(g_d3dpp));
g_d3dpp.Windowed = TRUE;
g_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
g_d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
g_d3dpp.EnableAutoDepthStencil = TRUE;
g_d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; // Present with vsync
//g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // Present without vsync, maximum unthrottled framerate
if (g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &g_d3dpp, &g_pd3dDevice) < 0)
return false;
return true;
}
void CleanupDeviceD3D()
{
if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; }
if (g_pD3D) { g_pD3D->Release(); g_pD3D = NULL; }
}
void ResetDevice()
{
ImGui_ImplDX9_InvalidateDeviceObjects();
HRESULT hr = g_pd3dDevice->Reset(&g_d3dpp);
if (hr == D3DERR_INVALIDCALL)
IM_ASSERT(0);
ImGui_ImplDX9_CreateDeviceObjects();
}
// Win32 message handler
extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
return true;
switch (msg)
{
case WM_SIZE:
if (g_pd3dDevice != NULL && wParam != SIZE_MINIMIZED)
{
g_d3dpp.BackBufferWidth = LOWORD(lParam);
g_d3dpp.BackBufferHeight = HIWORD(lParam);
ResetDevice();
}
return 0;
case WM_SYSCOMMAND:
if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu
return 0;
break;
case WM_DESTROY:
::PostQuitMessage(0);
return 0;
}
return ::DefWindowProc(hWnd, msg, wParam, lParam);
}

View File

@ -15,6 +15,9 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2019-05-11: Inputs: Don't filter character value from ALLEGRO_EVENT_KEY_CHAR before calling AddInputCharacter().
// 2019-04-30: Renderer: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
// 2018-11-30: Platform: Added touchscreen support.
// 2018-11-30: Misc: Setting up io.BackendPlatformName/io.BackendRendererName so they can be displayed in the About Window. // 2018-11-30: Misc: Setting up io.BackendPlatformName/io.BackendRendererName so they can be displayed in the About Window.
// 2018-06-13: Platform: Added clipboard support (from Allegro 5.1.12). // 2018-06-13: Platform: Added clipboard support (from Allegro 5.1.12).
// 2018-06-13: Renderer: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle. // 2018-06-13: Renderer: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle.
@ -59,19 +62,9 @@ struct ImDrawVertAllegro
ALLEGRO_COLOR col; ALLEGRO_COLOR col;
}; };
// Render function. static void ImGui_ImplAllegro5_SetupRenderState(ImDrawData* draw_data)
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
{ {
// Backup Allegro state that will be modified // Setup blending
ALLEGRO_TRANSFORM last_transform = *al_get_current_transform();
ALLEGRO_TRANSFORM last_projection_transform = *al_get_current_projection_transform();
int last_clip_x, last_clip_y, last_clip_w, last_clip_h;
al_get_clipping_rectangle(&last_clip_x, &last_clip_y, &last_clip_w, &last_clip_h);
int last_blender_op, last_blender_src, last_blender_dst;
al_get_blender(&last_blender_op, &last_blender_src, &last_blender_dst);
// Setup render state
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
// Setup orthographic projection matrix // Setup orthographic projection matrix
@ -87,7 +80,28 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
al_orthographic_transform(&transform, L, T, 1.0f, R, B, -1.0f); al_orthographic_transform(&transform, L, T, 1.0f, R, B, -1.0f);
al_use_projection_transform(&transform); al_use_projection_transform(&transform);
} }
}
// Render function.
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
{
// Avoid rendering when minimized
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
return;
// Backup Allegro state that will be modified
ALLEGRO_TRANSFORM last_transform = *al_get_current_transform();
ALLEGRO_TRANSFORM last_projection_transform = *al_get_current_projection_transform();
int last_clip_x, last_clip_y, last_clip_w, last_clip_h;
al_get_clipping_rectangle(&last_clip_x, &last_clip_y, &last_clip_w, &last_clip_h);
int last_blender_op, last_blender_src, last_blender_dst;
al_get_blender(&last_blender_op, &last_blender_src, &last_blender_dst);
// Setup desired render state
ImGui_ImplAllegro5_SetupRenderState(draw_data);
// Render command lists
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];
@ -122,19 +136,26 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
indices = (const int*)cmd_list->IdxBuffer.Data; indices = (const int*)cmd_list->IdxBuffer.Data;
} }
// Render command lists
int idx_offset = 0; int idx_offset = 0;
ImVec2 pos = draw_data->DisplayPos; ImVec2 clip_off = draw_data->DisplayPos;
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{ {
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback) if (pcmd->UserCallback)
{ {
// User callback, registered via ImDrawList::AddCallback()
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplAllegro5_SetupRenderState(draw_data);
else
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(cmd_list, pcmd);
} }
else else
{ {
// Draw
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId; ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x - pos.x, pcmd->ClipRect.y - pos.y, pcmd->ClipRect.z - pcmd->ClipRect.x, pcmd->ClipRect.w - pcmd->ClipRect.y); al_set_clipping_rectangle(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y, pcmd->ClipRect.z - pcmd->ClipRect.x, pcmd->ClipRect.w - pcmd->ClipRect.y);
al_draw_prim(&vertices[0], g_VertexDecl, texture, idx_offset, idx_offset + pcmd->ElemCount, ALLEGRO_PRIM_TRIANGLE_LIST); al_draw_prim(&vertices[0], g_VertexDecl, texture, idx_offset, idx_offset + pcmd->ElemCount, ALLEGRO_PRIM_TRIANGLE_LIST);
} }
idx_offset += pcmd->ElemCount; idx_offset += pcmd->ElemCount;
@ -267,6 +288,7 @@ bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display)
io.KeyMap[ImGuiKey_X] = ALLEGRO_KEY_X; io.KeyMap[ImGuiKey_X] = ALLEGRO_KEY_X;
io.KeyMap[ImGuiKey_Y] = ALLEGRO_KEY_Y; io.KeyMap[ImGuiKey_Y] = ALLEGRO_KEY_Y;
io.KeyMap[ImGuiKey_Z] = ALLEGRO_KEY_Z; io.KeyMap[ImGuiKey_Z] = ALLEGRO_KEY_Z;
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
#if ALLEGRO_HAS_CLIPBOARD #if ALLEGRO_HAS_CLIPBOARD
io.SetClipboardTextFn = ImGui_ImplAllegro5_SetClipboardText; io.SetClipboardTextFn = ImGui_ImplAllegro5_SetClipboardText;
@ -304,13 +326,35 @@ bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT *ev)
switch (ev->type) switch (ev->type)
{ {
case ALLEGRO_EVENT_MOUSE_AXES: case ALLEGRO_EVENT_MOUSE_AXES:
if (ev->mouse.display == g_Display)
{
io.MouseWheel += ev->mouse.dz; io.MouseWheel += ev->mouse.dz;
io.MouseWheelH += ev->mouse.dw; io.MouseWheelH += ev->mouse.dw;
io.MousePos = ImVec2(ev->mouse.x, ev->mouse.y);
}
return true;
case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN:
case ALLEGRO_EVENT_MOUSE_BUTTON_UP:
if (ev->mouse.display == g_Display && ev->mouse.button <= 5)
io.MouseDown[ev->mouse.button - 1] = (ev->type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN);
return true;
case ALLEGRO_EVENT_TOUCH_MOVE:
if (ev->touch.display == g_Display)
io.MousePos = ImVec2(ev->touch.x, ev->touch.y);
return true;
case ALLEGRO_EVENT_TOUCH_BEGIN:
case ALLEGRO_EVENT_TOUCH_END:
case ALLEGRO_EVENT_TOUCH_CANCEL:
if (ev->touch.display == g_Display && ev->touch.primary)
io.MouseDown[0] = (ev->type == ALLEGRO_EVENT_TOUCH_BEGIN);
return true;
case ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY:
if (ev->mouse.display == g_Display)
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
return true; return true;
case ALLEGRO_EVENT_KEY_CHAR: case ALLEGRO_EVENT_KEY_CHAR:
if (ev->keyboard.display == g_Display) if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000) io.AddInputCharacter((unsigned int)ev->keyboard.unichar);
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true; return true;
case ALLEGRO_EVENT_KEY_DOWN: case ALLEGRO_EVENT_KEY_DOWN:
case ALLEGRO_EVENT_KEY_UP: case ALLEGRO_EVENT_KEY_UP:
@ -375,21 +419,5 @@ void ImGui_ImplAllegro5_NewFrame()
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); io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
else
{
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
}
al_get_mouse_state(&mouse);
io.MouseDown[0] = mouse.buttons & (1 << 0);
io.MouseDown[1] = mouse.buttons & (1 << 1);
io.MouseDown[2] = mouse.buttons & (1 << 2);
ImGui_ImplAllegro5_UpdateMouseCursor(); ImGui_ImplAllegro5_UpdateMouseCursor();
} }

View File

@ -3,6 +3,7 @@
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp. // [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp.
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bits indices.
// 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 are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
@ -10,6 +11,8 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2019-05-29: DirectX10: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
// 2019-04-30: DirectX10: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
// 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile(). // 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile().
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. // 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
// 2018-07-13: DirectX10: Fixed unreleased resources in Init and Shutdown functions. // 2018-07-13: DirectX10: Fixed unreleased resources in Init and Shutdown functions.
@ -55,10 +58,45 @@ struct VERTEX_CONSTANT_BUFFER
float mvp[4][4]; float mvp[4][4];
}; };
static void ImGui_ImplDX10_SetupRenderState(ImDrawData* draw_data, ID3D10Device* ctx)
{
// Setup viewport
D3D10_VIEWPORT vp;
memset(&vp, 0, sizeof(D3D10_VIEWPORT));
vp.Width = (UINT)draw_data->DisplaySize.x;
vp.Height = (UINT)draw_data->DisplaySize.y;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = vp.TopLeftY = 0;
ctx->RSSetViewports(1, &vp);
// Bind shader and vertex buffers
unsigned int stride = sizeof(ImDrawVert);
unsigned int offset = 0;
ctx->IASetInputLayout(g_pInputLayout);
ctx->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset);
ctx->IASetIndexBuffer(g_pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
ctx->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ctx->VSSetShader(g_pVertexShader);
ctx->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer);
ctx->PSSetShader(g_pPixelShader);
ctx->PSSetSamplers(0, 1, &g_pFontSampler);
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
}
// Render function // Render function
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data) void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
{ {
// Avoid rendering when minimized
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
return;
ID3D10Device* ctx = g_pd3dDevice; ID3D10Device* ctx = g_pd3dDevice;
// Create and grow vertex/index buffers if needed // Create and grow vertex/index buffers if needed
@ -108,7 +146,7 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
g_pIB->Unmap(); g_pIB->Unmap();
// Setup orthographic projection matrix into our constant buffer // Setup orthographic projection matrix into our constant buffer
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
{ {
void* mapped_resource; void* mapped_resource;
if (g_pVertexConstantBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK) if (g_pVertexConstantBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
@ -168,38 +206,14 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
ctx->IAGetInputLayout(&old.InputLayout); ctx->IAGetInputLayout(&old.InputLayout);
// Setup viewport // Setup desired DX state
D3D10_VIEWPORT vp; ImGui_ImplDX10_SetupRenderState(draw_data, ctx);
memset(&vp, 0, sizeof(D3D10_VIEWPORT));
vp.Width = (UINT)draw_data->DisplaySize.x;
vp.Height = (UINT)draw_data->DisplaySize.y;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = vp.TopLeftY = 0;
ctx->RSSetViewports(1, &vp);
// Bind shader and vertex buffers
unsigned int stride = sizeof(ImDrawVert);
unsigned int offset = 0;
ctx->IASetInputLayout(g_pInputLayout);
ctx->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset);
ctx->IASetIndexBuffer(g_pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
ctx->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ctx->VSSetShader(g_pVertexShader);
ctx->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer);
ctx->PSSetShader(g_pPixelShader);
ctx->PSSetSamplers(0, 1, &g_pFontSampler);
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists // Render command lists
int vtx_offset = 0; // (Because we merged all buffers into a single one, we maintain our own offset into them)
int idx_offset = 0; int global_vtx_offset = 0;
ImVec2 pos = draw_data->DisplayPos; int global_idx_offset = 0;
ImVec2 clip_off = draw_data->DisplayPos;
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];
@ -208,23 +222,27 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback) if (pcmd->UserCallback)
{ {
// User callback (registered via ImDrawList::AddCallback) // User callback, registered via ImDrawList::AddCallback()
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplDX10_SetupRenderState(draw_data, ctx);
else
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(cmd_list, pcmd);
} }
else else
{ {
// Apply scissor/clipping rectangle // Apply scissor/clipping rectangle
const D3D10_RECT r = { (LONG)(pcmd->ClipRect.x - pos.x), (LONG)(pcmd->ClipRect.y - pos.y), (LONG)(pcmd->ClipRect.z - pos.x), (LONG)(pcmd->ClipRect.w - pos.y)}; const D3D10_RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y)};
ctx->RSSetScissorRects(1, &r); ctx->RSSetScissorRects(1, &r);
// Bind texture, Draw // Bind texture, Draw
ID3D10ShaderResourceView* texture_srv = (ID3D10ShaderResourceView*)pcmd->TextureId; ID3D10ShaderResourceView* texture_srv = (ID3D10ShaderResourceView*)pcmd->TextureId;
ctx->PSSetShaderResources(0, 1, &texture_srv); ctx->PSSetShaderResources(0, 1, &texture_srv);
ctx->DrawIndexed(pcmd->ElemCount, idx_offset, vtx_offset); ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
} }
idx_offset += pcmd->ElemCount;
} }
vtx_offset += cmd_list->VtxBuffer.Size; global_idx_offset += cmd_list->IdxBuffer.Size;
global_vtx_offset += cmd_list->VtxBuffer.Size;
} }
// Restore modified DX state // Restore modified DX state
@ -468,8 +486,10 @@ void ImGui_ImplDX10_InvalidateDeviceObjects()
bool ImGui_ImplDX10_Init(ID3D10Device* device) bool ImGui_ImplDX10_Init(ID3D10Device* device)
{ {
// Setup back-end capabilities flags
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.BackendRendererName = "imgui_impl_dx10"; io.BackendRendererName = "imgui_impl_dx10";
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
// Get factory from device // Get factory from device
IDXGIDevice* pDXGIDevice = NULL; IDXGIDevice* pDXGIDevice = NULL;
@ -485,6 +505,7 @@ bool ImGui_ImplDX10_Init(ID3D10Device* device)
} }
if (pDXGIDevice) pDXGIDevice->Release(); if (pDXGIDevice) pDXGIDevice->Release();
if (pDXGIAdapter) pDXGIAdapter->Release(); if (pDXGIAdapter) pDXGIAdapter->Release();
g_pd3dDevice->AddRef();
return true; return true;
} }
@ -493,7 +514,7 @@ void ImGui_ImplDX10_Shutdown()
{ {
ImGui_ImplDX10_InvalidateDeviceObjects(); ImGui_ImplDX10_InvalidateDeviceObjects();
if (g_pFactory) { g_pFactory->Release(); g_pFactory = NULL; } if (g_pFactory) { g_pFactory->Release(); g_pFactory = NULL; }
g_pd3dDevice = NULL; if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; }
} }
void ImGui_ImplDX10_NewFrame() void ImGui_ImplDX10_NewFrame()

View File

@ -3,6 +3,7 @@
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp. // [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp.
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bits indices.
// 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 are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.

View File

@ -3,6 +3,7 @@
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp. // [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp.
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bits indices.
// 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 are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp
@ -10,6 +11,8 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2019-05-29: DirectX11: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
// 2019-04-30: DirectX11: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
// 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile(). // 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile().
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. // 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
// 2018-08-01: DirectX11: Querying for IDXGIFactory instead of IDXGIFactory1 to increase compatibility. // 2018-08-01: DirectX11: Querying for IDXGIFactory instead of IDXGIFactory1 to increase compatibility.
@ -55,10 +58,45 @@ struct VERTEX_CONSTANT_BUFFER
float mvp[4][4]; float mvp[4][4];
}; };
static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceContext* ctx)
{
// Setup viewport
D3D11_VIEWPORT vp;
memset(&vp, 0, sizeof(D3D11_VIEWPORT));
vp.Width = draw_data->DisplaySize.x;
vp.Height = draw_data->DisplaySize.y;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = vp.TopLeftY = 0;
ctx->RSSetViewports(1, &vp);
// Setup shader and vertex buffers
unsigned int stride = sizeof(ImDrawVert);
unsigned int offset = 0;
ctx->IASetInputLayout(g_pInputLayout);
ctx->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset);
ctx->IASetIndexBuffer(g_pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ctx->VSSetShader(g_pVertexShader, NULL, 0);
ctx->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer);
ctx->PSSetShader(g_pPixelShader, NULL, 0);
ctx->PSSetSamplers(0, 1, &g_pFontSampler);
// Setup blend state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
}
// Render function // Render function
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data) void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
{ {
// Avoid rendering when minimized
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
return;
ID3D11DeviceContext* ctx = g_pd3dDeviceContext; ID3D11DeviceContext* ctx = g_pd3dDeviceContext;
// Create and grow vertex/index buffers if needed // Create and grow vertex/index buffers if needed
@ -90,7 +128,7 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
return; return;
} }
// Copy and convert all vertices into a single contiguous buffer // Upload vertex/index data into a single contiguous GPU buffer
D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource; D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource;
if (ctx->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;
@ -110,7 +148,7 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
ctx->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
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
{ {
D3D11_MAPPED_SUBRESOURCE mapped_resource; D3D11_MAPPED_SUBRESOURCE mapped_resource;
if (ctx->Map(g_pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK) if (ctx->Map(g_pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
@ -173,63 +211,43 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
ctx->IAGetInputLayout(&old.InputLayout); ctx->IAGetInputLayout(&old.InputLayout);
// Setup viewport // Setup desired DX state
D3D11_VIEWPORT vp; ImGui_ImplDX11_SetupRenderState(draw_data, ctx);
memset(&vp, 0, sizeof(D3D11_VIEWPORT));
vp.Width = draw_data->DisplaySize.x;
vp.Height = draw_data->DisplaySize.y;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = vp.TopLeftY = 0;
ctx->RSSetViewports(1, &vp);
// Bind shader and vertex buffers
unsigned int stride = sizeof(ImDrawVert);
unsigned int offset = 0;
ctx->IASetInputLayout(g_pInputLayout);
ctx->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset);
ctx->IASetIndexBuffer(g_pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ctx->VSSetShader(g_pVertexShader, NULL, 0);
ctx->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer);
ctx->PSSetShader(g_pPixelShader, NULL, 0);
ctx->PSSetSamplers(0, 1, &g_pFontSampler);
// Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
// Render command lists // Render command lists
int vtx_offset = 0; // (Because we merged all buffers into a single one, we maintain our own offset into them)
int idx_offset = 0; int global_idx_offset = 0;
ImVec2 pos = draw_data->DisplayPos; int global_vtx_offset = 0;
ImVec2 clip_off = draw_data->DisplayPos;
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];
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{ {
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback) if (pcmd->UserCallback != NULL)
{ {
// User callback (registered via ImDrawList::AddCallback) // User callback, registered via ImDrawList::AddCallback()
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplDX11_SetupRenderState(draw_data, ctx);
else
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(cmd_list, pcmd);
} }
else else
{ {
// Apply scissor/clipping rectangle // Apply scissor/clipping rectangle
const D3D11_RECT r = { (LONG)(pcmd->ClipRect.x - pos.x), (LONG)(pcmd->ClipRect.y - pos.y), (LONG)(pcmd->ClipRect.z - pos.x), (LONG)(pcmd->ClipRect.w - pos.y) }; const D3D11_RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y) };
ctx->RSSetScissorRects(1, &r); ctx->RSSetScissorRects(1, &r);
// Bind texture, Draw // Bind texture, Draw
ID3D11ShaderResourceView* texture_srv = (ID3D11ShaderResourceView*)pcmd->TextureId; ID3D11ShaderResourceView* texture_srv = (ID3D11ShaderResourceView*)pcmd->TextureId;
ctx->PSSetShaderResources(0, 1, &texture_srv); ctx->PSSetShaderResources(0, 1, &texture_srv);
ctx->DrawIndexed(pcmd->ElemCount, idx_offset, vtx_offset); ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
} }
idx_offset += pcmd->ElemCount;
} }
vtx_offset += cmd_list->VtxBuffer.Size; global_idx_offset += cmd_list->IdxBuffer.Size;
global_vtx_offset += cmd_list->VtxBuffer.Size;
} }
// Restore modified DX state // Restore modified DX state
@ -475,8 +493,10 @@ void ImGui_ImplDX11_InvalidateDeviceObjects()
bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context) bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context)
{ {
// Setup back-end capabilities flags
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.BackendRendererName = "imgui_impl_dx11"; io.BackendRendererName = "imgui_impl_dx11";
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
// Get factory from device // Get factory from device
IDXGIDevice* pDXGIDevice = NULL; IDXGIDevice* pDXGIDevice = NULL;
@ -493,6 +513,8 @@ bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_co
} }
if (pDXGIDevice) pDXGIDevice->Release(); if (pDXGIDevice) pDXGIDevice->Release();
if (pDXGIAdapter) pDXGIAdapter->Release(); if (pDXGIAdapter) pDXGIAdapter->Release();
g_pd3dDevice->AddRef();
g_pd3dDeviceContext->AddRef();
return true; return true;
} }
@ -501,8 +523,8 @@ void ImGui_ImplDX11_Shutdown()
{ {
ImGui_ImplDX11_InvalidateDeviceObjects(); ImGui_ImplDX11_InvalidateDeviceObjects();
if (g_pFactory) { g_pFactory->Release(); g_pFactory = NULL; } if (g_pFactory) { g_pFactory->Release(); g_pFactory = NULL; }
g_pd3dDevice = NULL; if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; }
g_pd3dDeviceContext = NULL; if (g_pd3dDeviceContext) { g_pd3dDeviceContext->Release(); g_pd3dDeviceContext = NULL; }
} }
void ImGui_ImplDX11_NewFrame() void ImGui_ImplDX11_NewFrame()

View File

@ -3,6 +3,7 @@
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp. // [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp.
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bits indices.
// 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 are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.

View File

@ -3,6 +3,7 @@
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp. // [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp.
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bits indices.
// Issues: // Issues:
// [ ] 64-bit only for now! (Because sizeof(ImTextureId) == sizeof(void*)). See github.com/ocornut/imgui/pull/301 // [ ] 64-bit only for now! (Because sizeof(ImTextureId) == sizeof(void*)). See github.com/ocornut/imgui/pull/301
@ -12,6 +13,9 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2019-05-29: DirectX12: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
// 2019-04-30: DirectX12: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
// 2019-03-29: Misc: Various minor tidying up.
// 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile(). // 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile().
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. // 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
// 2018-06-12: DirectX12: Moved the ID3D12GraphicsCommandList* parameter from NewFrame() to RenderDrawData(). // 2018-06-12: DirectX12: Moved the ID3D12GraphicsCommandList* parameter from NewFrame() to RenderDrawData().
@ -43,10 +47,10 @@ static D3D12_GPU_DESCRIPTOR_HANDLE g_hFontSrvGpuDescHandle = {};
struct FrameResources struct FrameResources
{ {
ID3D12Resource* IB; ID3D12Resource* IndexBuffer;
ID3D12Resource* VB; ID3D12Resource* VertexBuffer;
int VertexBufferSize;
int IndexBufferSize; int IndexBufferSize;
int VertexBufferSize;
}; };
static FrameResources* g_pFrameResources = NULL; static FrameResources* g_pFrameResources = NULL;
static UINT g_numFramesInFlight = 0; static UINT g_numFramesInFlight = 0;
@ -57,97 +61,12 @@ struct VERTEX_CONSTANT_BUFFER
float mvp[4][4]; float mvp[4][4];
}; };
// Render function static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx, FrameResources* fr)
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx)
{ {
// FIXME: I'm assuming that this only gets called once per frame!
// If not, we can't just re-allocate the IB or VB, we'll have to do a proper allocator.
g_frameIndex = g_frameIndex + 1;
FrameResources* frameResources = &g_pFrameResources[g_frameIndex % g_numFramesInFlight];
ID3D12Resource* g_pVB = frameResources->VB;
ID3D12Resource* g_pIB = frameResources->IB;
int g_VertexBufferSize = frameResources->VertexBufferSize;
int g_IndexBufferSize = frameResources->IndexBufferSize;
// Create and grow vertex/index buffers if needed
if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount)
{
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
g_VertexBufferSize = draw_data->TotalVtxCount + 5000;
D3D12_HEAP_PROPERTIES props;
memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES));
props.Type = D3D12_HEAP_TYPE_UPLOAD;
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
D3D12_RESOURCE_DESC desc;
memset(&desc, 0, sizeof(D3D12_RESOURCE_DESC));
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
desc.Width = g_VertexBufferSize * sizeof(ImDrawVert);
desc.Height = 1;
desc.DepthOrArraySize = 1;
desc.MipLevels = 1;
desc.Format = DXGI_FORMAT_UNKNOWN;
desc.SampleDesc.Count = 1;
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
if (g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&g_pVB)) < 0)
return;
frameResources->VB = g_pVB;
frameResources->VertexBufferSize = g_VertexBufferSize;
}
if (!g_pIB || g_IndexBufferSize < draw_data->TotalIdxCount)
{
if (g_pIB) { g_pIB->Release(); g_pIB = NULL; }
g_IndexBufferSize = draw_data->TotalIdxCount + 10000;
D3D12_HEAP_PROPERTIES props;
memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES));
props.Type = D3D12_HEAP_TYPE_UPLOAD;
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
D3D12_RESOURCE_DESC desc;
memset(&desc, 0, sizeof(D3D12_RESOURCE_DESC));
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
desc.Width = g_IndexBufferSize * sizeof(ImDrawIdx);
desc.Height = 1;
desc.DepthOrArraySize = 1;
desc.MipLevels = 1;
desc.Format = DXGI_FORMAT_UNKNOWN;
desc.SampleDesc.Count = 1;
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
if (g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&g_pIB)) < 0)
return;
frameResources->IB = g_pIB;
frameResources->IndexBufferSize = g_IndexBufferSize;
}
// Copy and convert all vertices into a single contiguous buffer
void* vtx_resource, *idx_resource;
D3D12_RANGE range;
memset(&range, 0, sizeof(D3D12_RANGE));
if (g_pVB->Map(0, &range, &vtx_resource) != S_OK)
return;
if (g_pIB->Map(0, &range, &idx_resource) != S_OK)
return;
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource;
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource;
for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
vtx_dst += cmd_list->VtxBuffer.Size;
idx_dst += cmd_list->IdxBuffer.Size;
}
g_pVB->Unmap(0, &range);
g_pIB->Unmap(0, &range);
// Setup orthographic projection matrix into our constant buffer // Setup orthographic projection matrix into our constant buffer
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right).
VERTEX_CONSTANT_BUFFER vertex_constant_buffer; VERTEX_CONSTANT_BUFFER vertex_constant_buffer;
{ {
VERTEX_CONSTANT_BUFFER* constant_buffer = &vertex_constant_buffer;
float L = draw_data->DisplayPos.x; float L = draw_data->DisplayPos.x;
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
float T = draw_data->DisplayPos.y; float T = draw_data->DisplayPos.y;
@ -159,7 +78,7 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
{ 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(&constant_buffer->mvp, mvp, sizeof(mvp)); memcpy(&vertex_constant_buffer.mvp, mvp, sizeof(mvp));
} }
// Setup viewport // Setup viewport
@ -177,14 +96,14 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
unsigned int offset = 0; unsigned int offset = 0;
D3D12_VERTEX_BUFFER_VIEW vbv; D3D12_VERTEX_BUFFER_VIEW vbv;
memset(&vbv, 0, sizeof(D3D12_VERTEX_BUFFER_VIEW)); memset(&vbv, 0, sizeof(D3D12_VERTEX_BUFFER_VIEW));
vbv.BufferLocation = g_pVB->GetGPUVirtualAddress() + offset; vbv.BufferLocation = fr->VertexBuffer->GetGPUVirtualAddress() + offset;
vbv.SizeInBytes = g_VertexBufferSize * stride; vbv.SizeInBytes = fr->VertexBufferSize * stride;
vbv.StrideInBytes = stride; vbv.StrideInBytes = stride;
ctx->IASetVertexBuffers(0, 1, &vbv); ctx->IASetVertexBuffers(0, 1, &vbv);
D3D12_INDEX_BUFFER_VIEW ibv; D3D12_INDEX_BUFFER_VIEW ibv;
memset(&ibv, 0, sizeof(D3D12_INDEX_BUFFER_VIEW)); memset(&ibv, 0, sizeof(D3D12_INDEX_BUFFER_VIEW));
ibv.BufferLocation = g_pIB->GetGPUVirtualAddress(); ibv.BufferLocation = fr->IndexBuffer->GetGPUVirtualAddress();
ibv.SizeInBytes = g_IndexBufferSize * sizeof(ImDrawIdx); ibv.SizeInBytes = fr->IndexBufferSize * sizeof(ImDrawIdx);
ibv.Format = sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT; ibv.Format = sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT;
ctx->IASetIndexBuffer(&ibv); ctx->IASetIndexBuffer(&ibv);
ctx->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); ctx->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
@ -192,34 +111,127 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
ctx->SetGraphicsRootSignature(g_pRootSignature); ctx->SetGraphicsRootSignature(g_pRootSignature);
ctx->SetGraphicsRoot32BitConstants(0, 16, &vertex_constant_buffer, 0); ctx->SetGraphicsRoot32BitConstants(0, 16, &vertex_constant_buffer, 0);
// Setup render state // Setup blend factor
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f }; const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendFactor(blend_factor); ctx->OMSetBlendFactor(blend_factor);
}
// Render function
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx)
{
// Avoid rendering when minimized
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
return;
// FIXME: I'm assuming that this only gets called once per frame!
// If not, we can't just re-allocate the IB or VB, we'll have to do a proper allocator.
g_frameIndex = g_frameIndex + 1;
FrameResources* fr = &g_pFrameResources[g_frameIndex % g_numFramesInFlight];
// Create and grow vertex/index buffers if needed
if (fr->VertexBuffer == NULL || fr->VertexBufferSize < draw_data->TotalVtxCount)
{
if (fr->VertexBuffer != NULL) { fr->VertexBuffer->Release(); fr->VertexBuffer = NULL; }
fr->VertexBufferSize = draw_data->TotalVtxCount + 5000;
D3D12_HEAP_PROPERTIES props;
memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES));
props.Type = D3D12_HEAP_TYPE_UPLOAD;
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
D3D12_RESOURCE_DESC desc;
memset(&desc, 0, sizeof(D3D12_RESOURCE_DESC));
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
desc.Width = fr->VertexBufferSize * sizeof(ImDrawVert);
desc.Height = 1;
desc.DepthOrArraySize = 1;
desc.MipLevels = 1;
desc.Format = DXGI_FORMAT_UNKNOWN;
desc.SampleDesc.Count = 1;
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
if (g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&fr->VertexBuffer)) < 0)
return;
}
if (fr->IndexBuffer == NULL || fr->IndexBufferSize < draw_data->TotalIdxCount)
{
if (fr->IndexBuffer != NULL) { fr->IndexBuffer->Release(); fr->IndexBuffer = NULL; }
fr->IndexBufferSize = draw_data->TotalIdxCount + 10000;
D3D12_HEAP_PROPERTIES props;
memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES));
props.Type = D3D12_HEAP_TYPE_UPLOAD;
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
D3D12_RESOURCE_DESC desc;
memset(&desc, 0, sizeof(D3D12_RESOURCE_DESC));
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
desc.Width = fr->IndexBufferSize * sizeof(ImDrawIdx);
desc.Height = 1;
desc.DepthOrArraySize = 1;
desc.MipLevels = 1;
desc.Format = DXGI_FORMAT_UNKNOWN;
desc.SampleDesc.Count = 1;
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
if (g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&fr->IndexBuffer)) < 0)
return;
}
// Upload vertex/index data into a single contiguous GPU buffer
void* vtx_resource, *idx_resource;
D3D12_RANGE range;
memset(&range, 0, sizeof(D3D12_RANGE));
if (fr->VertexBuffer->Map(0, &range, &vtx_resource) != S_OK)
return;
if (fr->IndexBuffer->Map(0, &range, &idx_resource) != S_OK)
return;
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource;
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource;
for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
vtx_dst += cmd_list->VtxBuffer.Size;
idx_dst += cmd_list->IdxBuffer.Size;
}
fr->VertexBuffer->Unmap(0, &range);
fr->IndexBuffer->Unmap(0, &range);
// Setup desired DX state
ImGui_ImplDX12_SetupRenderState(draw_data, ctx, fr);
// Render command lists // Render command lists
int vtx_offset = 0; // (Because we merged all buffers into a single one, we maintain our own offset into them)
int idx_offset = 0; int global_vtx_offset = 0;
ImVec2 pos = draw_data->DisplayPos; int global_idx_offset = 0;
ImVec2 clip_off = draw_data->DisplayPos;
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];
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{ {
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback) if (pcmd->UserCallback != NULL)
{ {
// User callback, registered via ImDrawList::AddCallback()
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplDX12_SetupRenderState(draw_data, ctx, fr);
else
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(cmd_list, pcmd);
} }
else else
{ {
const D3D12_RECT r = { (LONG)(pcmd->ClipRect.x - pos.x), (LONG)(pcmd->ClipRect.y - pos.y), (LONG)(pcmd->ClipRect.z - pos.x), (LONG)(pcmd->ClipRect.w - pos.y) }; // Apply Scissor, Bind texture, Draw
const D3D12_RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y) };
ctx->SetGraphicsRootDescriptorTable(1, *(D3D12_GPU_DESCRIPTOR_HANDLE*)&pcmd->TextureId); ctx->SetGraphicsRootDescriptorTable(1, *(D3D12_GPU_DESCRIPTOR_HANDLE*)&pcmd->TextureId);
ctx->RSSetScissorRects(1, &r); ctx->RSSetScissorRects(1, &r);
ctx->DrawIndexedInstanced(pcmd->ElemCount, 1, idx_offset, vtx_offset, 0); ctx->DrawIndexedInstanced(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
} }
idx_offset += pcmd->ElemCount;
} }
vtx_offset += cmd_list->VtxBuffer.Size; global_idx_offset += cmd_list->IdxBuffer.Size;
global_vtx_offset += cmd_list->VtxBuffer.Size;
} }
} }
@ -490,9 +502,9 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
// Create the input layout // Create the input layout
static D3D12_INPUT_ELEMENT_DESC local_layout[] = { static D3D12_INPUT_ELEMENT_DESC local_layout[] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->pos), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, IM_OFFSETOF(ImDrawVert, pos), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->uv), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, IM_OFFSETOF(ImDrawVert, uv), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, IM_OFFSETOF(ImDrawVert, col), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
}; };
psoDesc.InputLayout = { local_layout, 3 }; psoDesc.InputLayout = { local_layout, 3 };
} }
@ -576,23 +588,27 @@ void ImGui_ImplDX12_InvalidateDeviceObjects()
if (!g_pd3dDevice) if (!g_pd3dDevice)
return; return;
ImGuiIO& io = ImGui::GetIO();
if (g_pVertexShaderBlob) { g_pVertexShaderBlob->Release(); g_pVertexShaderBlob = NULL; } if (g_pVertexShaderBlob) { g_pVertexShaderBlob->Release(); g_pVertexShaderBlob = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; } if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
if (g_pRootSignature) { g_pRootSignature->Release(); g_pRootSignature = NULL; } if (g_pRootSignature) { g_pRootSignature->Release(); g_pRootSignature = NULL; }
if (g_pPipelineState) { g_pPipelineState->Release(); g_pPipelineState = NULL; } if (g_pPipelineState) { g_pPipelineState->Release(); g_pPipelineState = NULL; }
if (g_pFontTextureResource) { g_pFontTextureResource->Release(); g_pFontTextureResource = NULL; ImGui::GetIO().Fonts->TexID = NULL; } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well. if (g_pFontTextureResource) { g_pFontTextureResource->Release(); g_pFontTextureResource = NULL; io.Fonts->TexID = NULL; } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
for (UINT i = 0; i < g_numFramesInFlight; i++) for (UINT i = 0; i < g_numFramesInFlight; i++)
{ {
if (g_pFrameResources[i].IB) { g_pFrameResources[i].IB->Release(); g_pFrameResources[i].IB = NULL; } FrameResources* fr = &g_pFrameResources[i];
if (g_pFrameResources[i].VB) { g_pFrameResources[i].VB->Release(); g_pFrameResources[i].VB = NULL; } if (fr->IndexBuffer) { fr->IndexBuffer->Release(); fr->IndexBuffer = NULL; }
if (fr->VertexBuffer) { fr->VertexBuffer->Release(); fr->VertexBuffer = NULL; }
} }
} }
bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format,
D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle) D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle)
{ {
// Setup back-end capabilities flags
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.BackendRendererName = "imgui_impl_dx12"; io.BackendRendererName = "imgui_impl_dx12";
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
g_pd3dDevice = device; g_pd3dDevice = device;
g_RTVFormat = rtv_format; g_RTVFormat = rtv_format;
@ -605,10 +621,11 @@ bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FO
// Create buffers with a default size (they will later be grown as needed) // Create buffers with a default size (they will later be grown as needed)
for (int i = 0; i < num_frames_in_flight; i++) for (int i = 0; i < num_frames_in_flight; i++)
{ {
g_pFrameResources[i].IB = NULL; FrameResources* fr = &g_pFrameResources[i];
g_pFrameResources[i].VB = NULL; fr->IndexBuffer = NULL;
g_pFrameResources[i].VertexBufferSize = 5000; fr->VertexBuffer = NULL;
g_pFrameResources[i].IndexBufferSize = 10000; fr->IndexBufferSize = 10000;
fr->VertexBufferSize = 5000;
} }
return true; return true;
@ -618,10 +635,10 @@ void ImGui_ImplDX12_Shutdown()
{ {
ImGui_ImplDX12_InvalidateDeviceObjects(); ImGui_ImplDX12_InvalidateDeviceObjects();
delete[] g_pFrameResources; delete[] g_pFrameResources;
g_pFrameResources = NULL;
g_pd3dDevice = NULL; g_pd3dDevice = NULL;
g_hFontSrvCpuDescHandle.ptr = 0; g_hFontSrvCpuDescHandle.ptr = 0;
g_hFontSrvGpuDescHandle.ptr = 0; g_hFontSrvGpuDescHandle.ptr = 0;
g_pFrameResources = NULL;
g_numFramesInFlight = 0; g_numFramesInFlight = 0;
g_frameIndex = UINT_MAX; g_frameIndex = UINT_MAX;
} }

View File

@ -3,6 +3,7 @@
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp. // [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp.
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bits indices.
// Issues: // Issues:
// [ ] 64-bit only for now! (Because sizeof(ImTextureId) == sizeof(void*)). See github.com/ocornut/imgui/pull/301 // [ ] 64-bit only for now! (Because sizeof(ImTextureId) == sizeof(void*)). See github.com/ocornut/imgui/pull/301

View File

@ -3,6 +3,7 @@
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp. // [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp.
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bits indices.
// 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 are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
@ -10,6 +11,10 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2019-05-29: DirectX9: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
// 2019-04-30: DirectX9: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
// 2019-03-29: Misc: Fixed erroneous assert in ImGui_ImplDX9_InvalidateDeviceObjects().
// 2019-01-16: Misc: Disabled fog before drawing UI's. Fixes issue #2288.
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. // 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
// 2018-06-08: Misc: Extracted imgui_impl_dx9.cpp/.h away from the old combined DX9+Win32 example. // 2018-06-08: Misc: Extracted imgui_impl_dx9.cpp/.h away from the old combined DX9+Win32 example.
// 2018-06-08: DirectX9: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle. // 2018-06-08: DirectX9: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle.
@ -40,6 +45,62 @@ struct CUSTOMVERTEX
}; };
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1) #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data)
{
// Setup viewport
D3DVIEWPORT9 vp;
vp.X = vp.Y = 0;
vp.Width = (DWORD)draw_data->DisplaySize.x;
vp.Height = (DWORD)draw_data->DisplaySize.y;
vp.MinZ = 0.0f;
vp.MaxZ = 1.0f;
g_pd3dDevice->SetViewport(&vp);
// Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing, shade mode (for gradient)
g_pd3dDevice->SetPixelShader(NULL);
g_pd3dDevice->SetVertexShader(NULL);
g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, false);
g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, false);
g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
g_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, false);
g_pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, true);
g_pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
g_pd3dDevice->SetRenderState(D3DRS_FOGENABLE, false);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
// Setup orthographic projection matrix
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
// Being agnostic of whether <d3dx9.h> or <DirectXMath.h> can be used, we aren't relying on D3DXMatrixIdentity()/D3DXMatrixOrthoOffCenterLH() or DirectX::XMMatrixIdentity()/DirectX::XMMatrixOrthographicOffCenterLH()
{
float L = draw_data->DisplayPos.x + 0.5f;
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x + 0.5f;
float T = draw_data->DisplayPos.y + 0.5f;
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y + 0.5f;
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 } } };
D3DMATRIX mat_projection =
{ { {
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 function. // Render function.
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data) void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
@ -109,83 +170,40 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
g_pd3dDevice->SetIndices(g_pIB); g_pd3dDevice->SetIndices(g_pIB);
g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX); g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
// Setup viewport // Setup desired DX state
D3DVIEWPORT9 vp; ImGui_ImplDX9_SetupRenderState(draw_data);
vp.X = vp.Y = 0;
vp.Width = (DWORD)draw_data->DisplaySize.x;
vp.Height = (DWORD)draw_data->DisplaySize.y;
vp.MinZ = 0.0f;
vp.MaxZ = 1.0f;
g_pd3dDevice->SetViewport(&vp);
// Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing, shade mode (for gradient)
g_pd3dDevice->SetPixelShader(NULL);
g_pd3dDevice->SetVertexShader(NULL);
g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, false);
g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, false);
g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
g_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, false);
g_pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, true);
g_pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
// Setup orthographic projection matrix
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right).
// Being agnostic of whether <d3dx9.h> or <DirectXMath.h> can be used, we aren't relying on D3DXMatrixIdentity()/D3DXMatrixOrthoOffCenterLH() or DirectX::XMMatrixIdentity()/DirectX::XMMatrixOrthographicOffCenterLH()
{
float L = draw_data->DisplayPos.x + 0.5f;
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x + 0.5f;
float T = draw_data->DisplayPos.y + 0.5f;
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y + 0.5f;
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 } };
D3DMATRIX mat_projection =
{
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; // (Because we merged all buffers into a single one, we maintain our own offset into them)
int idx_offset = 0; int global_vtx_offset = 0;
ImVec2 pos = draw_data->DisplayPos; int global_idx_offset = 0;
ImVec2 clip_off = draw_data->DisplayPos;
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];
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{ {
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback) if (pcmd->UserCallback != NULL)
{ {
// User callback, registered via ImDrawList::AddCallback()
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplDX9_SetupRenderState(draw_data);
else
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(cmd_list, pcmd);
} }
else else
{ {
const RECT r = { (LONG)(pcmd->ClipRect.x - pos.x), (LONG)(pcmd->ClipRect.y - pos.y), (LONG)(pcmd->ClipRect.z - pos.x), (LONG)(pcmd->ClipRect.w - pos.y) }; const RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y) };
const LPDIRECT3DTEXTURE9 texture = (LPDIRECT3DTEXTURE9)pcmd->TextureId; const LPDIRECT3DTEXTURE9 texture = (LPDIRECT3DTEXTURE9)pcmd->TextureId;
g_pd3dDevice->SetTexture(0, texture); g_pd3dDevice->SetTexture(0, texture);
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, pcmd->VtxOffset + global_vtx_offset, 0, (UINT)cmd_list->VtxBuffer.Size, pcmd->IdxOffset + global_idx_offset, pcmd->ElemCount/3);
} }
idx_offset += pcmd->ElemCount;
} }
vtx_offset += cmd_list->VtxBuffer.Size; global_idx_offset += cmd_list->IdxBuffer.Size;
global_vtx_offset += cmd_list->VtxBuffer.Size;
} }
// Restore the DX9 transform // Restore the DX9 transform
@ -200,17 +218,20 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
bool ImGui_ImplDX9_Init(IDirect3DDevice9* device) bool ImGui_ImplDX9_Init(IDirect3DDevice9* device)
{ {
// Setup back-end capabilities flags
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.BackendRendererName = "imgui_impl_dx9"; io.BackendRendererName = "imgui_impl_dx9";
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
g_pd3dDevice = device; g_pd3dDevice = device;
g_pd3dDevice->AddRef();
return true; return true;
} }
void ImGui_ImplDX9_Shutdown() void ImGui_ImplDX9_Shutdown()
{ {
ImGui_ImplDX9_InvalidateDeviceObjects(); ImGui_ImplDX9_InvalidateDeviceObjects();
g_pd3dDevice = NULL; if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; }
} }
static bool ImGui_ImplDX9_CreateFontsTexture() static bool ImGui_ImplDX9_CreateFontsTexture()
@ -251,24 +272,9 @@ void ImGui_ImplDX9_InvalidateDeviceObjects()
{ {
if (!g_pd3dDevice) if (!g_pd3dDevice)
return; return;
if (g_pVB) if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
{ if (g_pIB) { g_pIB->Release(); g_pIB = NULL; }
g_pVB->Release(); if (g_FontTexture) { g_FontTexture->Release(); g_FontTexture = NULL; ImGui::GetIO().Fonts->TexID = NULL; } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
g_pVB = NULL;
}
if (g_pIB)
{
g_pIB->Release();
g_pIB = NULL;
}
// At this point note that we set ImGui::GetIO().Fonts->TexID to be == g_FontTexture, so clear both.
ImGuiIO& io = ImGui::GetIO();
IM_ASSERT(g_FontTexture == io.Fonts->TexID);
if (g_FontTexture)
g_FontTexture->Release();
g_FontTexture = NULL;
io.Fonts->TexID = NULL;
} }
void ImGui_ImplDX9_NewFrame() void ImGui_ImplDX9_NewFrame()

View File

@ -3,6 +3,7 @@
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp. // [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp.
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bits indices.
// 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 are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
@ -18,5 +19,5 @@ IMGUI_IMPL_API void ImGui_ImplDX9_NewFrame();
IMGUI_IMPL_API void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data); IMGUI_IMPL_API void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data);
// 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.
IMGUI_IMPL_API void ImGui_ImplDX9_InvalidateDeviceObjects();
IMGUI_IMPL_API bool ImGui_ImplDX9_CreateDeviceObjects(); IMGUI_IMPL_API bool ImGui_ImplDX9_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplDX9_InvalidateDeviceObjects();

View File

@ -1,29 +0,0 @@
// dear imgui: Platform Binding for FreeGLUT
// This needs to be used along with a Renderer (e.g. OpenGL2)
// Issues:
// [ ] Platform: GLUT is unable to distinguish e.g. Backspace from CTRL+H or TAB from CTRL+I
// [ ] Platform: Missing gamepad support.
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
// https://github.com/ocornut/imgui
#pragma once
IMGUI_IMPL_API bool ImGui_ImplFreeGLUT_Init();
IMGUI_IMPL_API void ImGui_ImplFreeGLUT_InstallFuncs();
IMGUI_IMPL_API void ImGui_ImplFreeGLUT_Shutdown();
IMGUI_IMPL_API void ImGui_ImplFreeGLUT_NewFrame();
// You can call ImGui_ImplFreeGLUT_InstallFuncs() to get all those functions installed automatically,
// or call them yourself from your own GLUT handlers. We are using the same weird names as GLUT for consistency..
//---------------------------------------- GLUT name --------------------------------------------- Decent Name ---------
IMGUI_IMPL_API void ImGui_ImplFreeGLUT_ReshapeFunc(int w, int h); // ~ ResizeFunc
IMGUI_IMPL_API void ImGui_ImplFreeGLUT_MotionFunc(int x, int y); // ~ MouseMoveFunc
IMGUI_IMPL_API void ImGui_ImplFreeGLUT_MouseFunc(int button, int state, int x, int y); // ~ MouseButtonFunc
IMGUI_IMPL_API void ImGui_ImplFreeGLUT_MouseWheelFunc(int button, int dir, int x, int y); // ~ MouseWheelFunc
IMGUI_IMPL_API void ImGui_ImplFreeGLUT_KeyboardFunc(unsigned char c, int x, int y); // ~ CharPressedFunc
IMGUI_IMPL_API void ImGui_ImplFreeGLUT_KeyboardUpFunc(unsigned char c, int x, int y); // ~ CharReleasedFunc
IMGUI_IMPL_API void ImGui_ImplFreeGLUT_SpecialFunc(int key, int x, int y); // ~ KeyPressedFunc
IMGUI_IMPL_API void ImGui_ImplFreeGLUT_SpecialUpFunc(int key, int x, int y); // ~ KeyReleasedFunc

View File

@ -15,6 +15,8 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2019-05-11: Inputs: Don't filter value from character callback before calling AddInputCharacter().
// 2019-03-12: Misc: Preserve DisplayFramebufferScale when main window is minimized.
// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window. // 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window.
// 2018-11-07: Inputs: When installing our GLFW callbacks, we save user's previously installed ones - if any - and chain call them. // 2018-11-07: Inputs: When installing our GLFW callbacks, we save user's previously installed ones - if any - and chain call them.
// 2018-08-01: Inputs: Workaround for Emscripten which doesn't seem to handle focus related calls. // 2018-08-01: Inputs: Workaround for Emscripten which doesn't seem to handle focus related calls.
@ -54,7 +56,7 @@ enum GlfwClientApi
GlfwClientApi_OpenGL, GlfwClientApi_OpenGL,
GlfwClientApi_Vulkan GlfwClientApi_Vulkan
}; };
static GLFWwindow* g_Window = NULL; static GLFWwindow* g_Window = NULL; // Main window
static GlfwClientApi g_ClientApi = GlfwClientApi_Unknown; static GlfwClientApi g_ClientApi = GlfwClientApi_Unknown;
static double g_Time = 0.0; static double g_Time = 0.0;
static bool g_MouseJustPressed[5] = { false, false, false, false, false }; static bool g_MouseJustPressed[5] = { false, false, false, false, false };
@ -119,8 +121,7 @@ void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c)
g_PrevUserCallbackChar(window, c); g_PrevUserCallbackChar(window, c);
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
if (c > 0 && c < 0x10000) io.AddInputCharacter(c);
io.AddInputCharacter((unsigned short)c);
} }
static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, GlfwClientApi client_api) static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, GlfwClientApi client_api)
@ -265,31 +266,13 @@ static void ImGui_ImplGlfw_UpdateMouseCursor()
} }
} }
void ImGui_ImplGlfw_NewFrame() static void ImGui_ImplGlfw_UpdateGamepads()
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IM_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built! It is generally built by the renderer back-end. Missing call to renderer _NewFrame() function? e.g. ImGui_ImplOpenGL3_NewFrame().");
// 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;
ImGui_ImplGlfw_UpdateMousePosAndButtons();
ImGui_ImplGlfw_UpdateMouseCursor();
// Gamepad navigation mapping [BETA]
memset(io.NavInputs, 0, sizeof(io.NavInputs)); memset(io.NavInputs, 0, sizeof(io.NavInputs));
if (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
{ return;
// Update gamepad inputs // Update gamepad inputs
#define MAP_BUTTON(NAV_NO, BUTTON_NO) { if (buttons_count > BUTTON_NO && buttons[BUTTON_NO] == GLFW_PRESS) io.NavInputs[NAV_NO] = 1.0f; } #define MAP_BUTTON(NAV_NO, BUTTON_NO) { if (buttons_count > BUTTON_NO && buttons[BUTTON_NO] == GLFW_PRESS) io.NavInputs[NAV_NO] = 1.0f; }
#define MAP_ANALOG(NAV_NO, AXIS_NO, V0, V1) { float v = (axes_count > AXIS_NO) ? axes[AXIS_NO] : V0; v = (v - V0) / (V1 - V0); if (v > 1.0f) v = 1.0f; if (io.NavInputs[NAV_NO] < v) io.NavInputs[NAV_NO] = v; } #define MAP_ANALOG(NAV_NO, AXIS_NO, V0, V1) { float v = (axes_count > AXIS_NO) ? axes[AXIS_NO] : V0; v = (v - V0) / (V1 - V0); if (v > 1.0f) v = 1.0f; if (io.NavInputs[NAV_NO] < v) io.NavInputs[NAV_NO] = v; }
@ -319,4 +302,29 @@ void ImGui_ImplGlfw_NewFrame()
else else
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad; io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
} }
void ImGui_ImplGlfw_NewFrame()
{
ImGuiIO& io = ImGui::GetIO();
IM_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built! It is generally built by the renderer back-end. Missing call to renderer _NewFrame() function? e.g. ImGui_ImplOpenGL3_NewFrame().");
// 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);
if (w > 0 && h > 0)
io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h);
// 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;
ImGui_ImplGlfw_UpdateMousePosAndButtons();
ImGui_ImplGlfw_UpdateMouseCursor();
// Update game controllers (if enabled and available)
ImGui_ImplGlfw_UpdateGamepads();
} }

View File

@ -1,8 +1,14 @@
// dear imgui: Platform Binding for FreeGLUT // dear imgui: Platform Binding for GLUT/FreeGLUT
// This needs to be used along with a Renderer (e.g. OpenGL2) // This needs to be used along with a Renderer (e.g. OpenGL2)
// !!! GLUT/FreeGLUT IS OBSOLETE SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!!
// !!! If someone or something is teaching you GLUT in 2019, you are being abused. Please show some resistance. !!!
// !!! Nowadays, prefer using GLFW or SDL instead!
// Issues: // Issues:
// [ ] Platform: GLUT is unable to distinguish e.g. Backspace from CTRL+H or TAB from CTRL+I // [ ] Platform: GLUT is unable to distinguish e.g. Backspace from CTRL+H or TAB from CTRL+I
// [ ] Platform: Missing mouse cursor shape/visibility support.
// [ ] Platform: Missing clipboard support (not supported by Glut).
// [ ] Platform: Missing gamepad support. // [ ] Platform: Missing gamepad support.
// 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.
@ -11,12 +17,18 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2019-04-03: Misc: Renamed imgui_impl_freeglut.cpp/.h to imgui_impl_glut.cpp/.h.
// 2019-03-25: Misc: Made io.DeltaTime always above zero.
// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window. // 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window.
// 2018-03-22: Added FreeGLUT Platform binding. // 2018-03-22: Added GLUT Platform binding.
#include "imgui.h" #include "imgui.h"
#include "imgui_impl_freeglut.h" #include "imgui_impl_glut.h"
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/freeglut.h> #include <GL/freeglut.h>
#endif
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff) #pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff)
@ -24,10 +36,10 @@
static int g_Time = 0; // Current time, in milliseconds static int g_Time = 0; // Current time, in milliseconds
bool ImGui_ImplFreeGLUT_Init() bool ImGui_ImplGLUT_Init()
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.BackendPlatformName ="imgui_impl_freeglut"; io.BackendPlatformName ="imgui_impl_glut";
g_Time = 0; g_Time = 0;
@ -57,36 +69,41 @@ bool ImGui_ImplFreeGLUT_Init()
return true; return true;
} }
void ImGui_ImplFreeGLUT_InstallFuncs() void ImGui_ImplGLUT_InstallFuncs()
{ {
glutReshapeFunc(ImGui_ImplFreeGLUT_ReshapeFunc); glutReshapeFunc(ImGui_ImplGLUT_ReshapeFunc);
glutMotionFunc(ImGui_ImplFreeGLUT_MotionFunc); glutMotionFunc(ImGui_ImplGLUT_MotionFunc);
glutPassiveMotionFunc(ImGui_ImplFreeGLUT_MotionFunc); glutPassiveMotionFunc(ImGui_ImplGLUT_MotionFunc);
glutMouseFunc(ImGui_ImplFreeGLUT_MouseFunc); glutMouseFunc(ImGui_ImplGLUT_MouseFunc);
glutMouseWheelFunc(ImGui_ImplFreeGLUT_MouseWheelFunc); #ifdef __FREEGLUT_EXT_H__
glutKeyboardFunc(ImGui_ImplFreeGLUT_KeyboardFunc); glutMouseWheelFunc(ImGui_ImplGLUT_MouseWheelFunc);
glutKeyboardUpFunc(ImGui_ImplFreeGLUT_KeyboardUpFunc); #endif
glutSpecialFunc(ImGui_ImplFreeGLUT_SpecialFunc); glutKeyboardFunc(ImGui_ImplGLUT_KeyboardFunc);
glutSpecialUpFunc(ImGui_ImplFreeGLUT_SpecialUpFunc); glutKeyboardUpFunc(ImGui_ImplGLUT_KeyboardUpFunc);
glutSpecialFunc(ImGui_ImplGLUT_SpecialFunc);
glutSpecialUpFunc(ImGui_ImplGLUT_SpecialUpFunc);
} }
void ImGui_ImplFreeGLUT_Shutdown() void ImGui_ImplGLUT_Shutdown()
{ {
} }
void ImGui_ImplFreeGLUT_NewFrame() void ImGui_ImplGLUT_NewFrame()
{ {
// Setup time step // Setup time step
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
int current_time = glutGet(GLUT_ELAPSED_TIME); int current_time = glutGet(GLUT_ELAPSED_TIME);
io.DeltaTime = (current_time - g_Time) / 1000.0f; int delta_time_ms = (current_time - g_Time);
if (delta_time_ms <= 0)
delta_time_ms = 1;
io.DeltaTime = delta_time_ms / 1000.0f;
g_Time = current_time; g_Time = current_time;
// Start the frame // Start the frame
ImGui::NewFrame(); ImGui::NewFrame();
} }
static void ImGui_ImplFreeGLUT_UpdateKeyboardMods() static void ImGui_ImplGLUT_UpdateKeyboardMods()
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
int mods = glutGetModifiers(); int mods = glutGetModifiers();
@ -95,13 +112,13 @@ static void ImGui_ImplFreeGLUT_UpdateKeyboardMods()
io.KeyAlt = (mods & GLUT_ACTIVE_ALT) != 0; io.KeyAlt = (mods & GLUT_ACTIVE_ALT) != 0;
} }
void ImGui_ImplFreeGLUT_KeyboardFunc(unsigned char c, int x, int y) void ImGui_ImplGLUT_KeyboardFunc(unsigned char c, int x, int y)
{ {
// Send character to imgui // Send character to imgui
//printf("char_down_func %d '%c'\n", c, c); //printf("char_down_func %d '%c'\n", c, c);
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
if (c >= 32) if (c >= 32)
io.AddInputCharacter((unsigned short)c); io.AddInputCharacter((unsigned int)c);
// Store letters in KeysDown[] array as both uppercase and lowercase + Handle GLUT translating CTRL+A..CTRL+Z as 1..26. // Store letters in KeysDown[] array as both uppercase and lowercase + Handle GLUT translating CTRL+A..CTRL+Z as 1..26.
// This is a hacky mess but GLUT is unable to distinguish e.g. a TAB key from CTRL+I so this is probably the best we can do here. // This is a hacky mess but GLUT is unable to distinguish e.g. a TAB key from CTRL+I so this is probably the best we can do here.
@ -113,11 +130,11 @@ void ImGui_ImplFreeGLUT_KeyboardFunc(unsigned char c, int x, int y)
io.KeysDown[c] = io.KeysDown[c - 'A' + 'a'] = true; io.KeysDown[c] = io.KeysDown[c - 'A' + 'a'] = true;
else else
io.KeysDown[c] = true; io.KeysDown[c] = true;
ImGui_ImplFreeGLUT_UpdateKeyboardMods(); ImGui_ImplGLUT_UpdateKeyboardMods();
(void)x; (void)y; // Unused (void)x; (void)y; // Unused
} }
void ImGui_ImplFreeGLUT_KeyboardUpFunc(unsigned char c, int x, int y) void ImGui_ImplGLUT_KeyboardUpFunc(unsigned char c, int x, int y)
{ {
//printf("char_up_func %d '%c'\n", c, c); //printf("char_up_func %d '%c'\n", c, c);
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
@ -129,31 +146,31 @@ void ImGui_ImplFreeGLUT_KeyboardUpFunc(unsigned char c, int x, int y)
io.KeysDown[c] = io.KeysDown[c - 'A' + 'a'] = false; io.KeysDown[c] = io.KeysDown[c - 'A' + 'a'] = false;
else else
io.KeysDown[c] = false; io.KeysDown[c] = false;
ImGui_ImplFreeGLUT_UpdateKeyboardMods(); ImGui_ImplGLUT_UpdateKeyboardMods();
(void)x; (void)y; // Unused (void)x; (void)y; // Unused
} }
void ImGui_ImplFreeGLUT_SpecialFunc(int key, int x, int y) void ImGui_ImplGLUT_SpecialFunc(int key, int x, int y)
{ {
//printf("key_down_func %d\n", key); //printf("key_down_func %d\n", key);
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
if (key + 256 < IM_ARRAYSIZE(io.KeysDown)) if (key + 256 < IM_ARRAYSIZE(io.KeysDown))
io.KeysDown[key + 256] = true; io.KeysDown[key + 256] = true;
ImGui_ImplFreeGLUT_UpdateKeyboardMods(); ImGui_ImplGLUT_UpdateKeyboardMods();
(void)x; (void)y; // Unused (void)x; (void)y; // Unused
} }
void ImGui_ImplFreeGLUT_SpecialUpFunc(int key, int x, int y) void ImGui_ImplGLUT_SpecialUpFunc(int key, int x, int y)
{ {
//printf("key_up_func %d\n", key); //printf("key_up_func %d\n", key);
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
if (key + 256 < IM_ARRAYSIZE(io.KeysDown)) if (key + 256 < IM_ARRAYSIZE(io.KeysDown))
io.KeysDown[key + 256] = false; io.KeysDown[key + 256] = false;
ImGui_ImplFreeGLUT_UpdateKeyboardMods(); ImGui_ImplGLUT_UpdateKeyboardMods();
(void)x; (void)y; // Unused (void)x; (void)y; // Unused
} }
void ImGui_ImplFreeGLUT_MouseFunc(int glut_button, int state, int x, int y) void ImGui_ImplGLUT_MouseFunc(int glut_button, int state, int x, int y)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.MousePos = ImVec2((float)x, (float)y); io.MousePos = ImVec2((float)x, (float)y);
@ -167,7 +184,8 @@ void ImGui_ImplFreeGLUT_MouseFunc(int glut_button, int state, int x, int y)
io.MouseDown[button] = false; io.MouseDown[button] = false;
} }
void ImGui_ImplFreeGLUT_MouseWheelFunc(int button, int dir, int x, int y) #ifdef __FREEGLUT_EXT_H__
void ImGui_ImplGLUT_MouseWheelFunc(int button, int dir, int x, int y)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.MousePos = ImVec2((float)x, (float)y); io.MousePos = ImVec2((float)x, (float)y);
@ -177,14 +195,15 @@ void ImGui_ImplFreeGLUT_MouseWheelFunc(int button, int dir, int x, int y)
io.MouseWheel -= 1.0; io.MouseWheel -= 1.0;
(void)button; // Unused (void)button; // Unused
} }
#endif
void ImGui_ImplFreeGLUT_ReshapeFunc(int w, int h) void ImGui_ImplGLUT_ReshapeFunc(int w, int h)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.DisplaySize = ImVec2((float)w, (float)h); io.DisplaySize = ImVec2((float)w, (float)h);
} }
void ImGui_ImplFreeGLUT_MotionFunc(int x, int y) void ImGui_ImplGLUT_MotionFunc(int x, int y)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.MousePos = ImVec2((float)x, (float)y); io.MousePos = ImVec2((float)x, (float)y);

View File

@ -0,0 +1,35 @@
// dear imgui: Platform Binding for GLUT/FreeGLUT
// This needs to be used along with a Renderer (e.g. OpenGL2)
// !!! GLUT/FreeGLUT IS OBSOLETE SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!!
// !!! If someone or something is teaching you GLUT in 2019, you are being abused. Please show some resistance. !!!
// !!! Nowadays, prefer using GLFW or SDL instead!
// Issues:
// [ ] Platform: GLUT is unable to distinguish e.g. Backspace from CTRL+H or TAB from CTRL+I
// [ ] Platform: Missing mouse cursor shape/visibility support.
// [ ] Platform: Missing clipboard support (not supported by Glut).
// [ ] Platform: Missing gamepad support.
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
// https://github.com/ocornut/imgui
#pragma once
IMGUI_IMPL_API bool ImGui_ImplGLUT_Init();
IMGUI_IMPL_API void ImGui_ImplGLUT_InstallFuncs();
IMGUI_IMPL_API void ImGui_ImplGLUT_Shutdown();
IMGUI_IMPL_API void ImGui_ImplGLUT_NewFrame();
// You can call ImGui_ImplGLUT_InstallFuncs() to get all those functions installed automatically,
// or call them yourself from your own GLUT handlers. We are using the same weird names as GLUT for consistency..
//---------------------------------------- GLUT name --------------------------------------------- Decent Name ---------
IMGUI_IMPL_API void ImGui_ImplGLUT_ReshapeFunc(int w, int h); // ~ ResizeFunc
IMGUI_IMPL_API void ImGui_ImplGLUT_MotionFunc(int x, int y); // ~ MouseMoveFunc
IMGUI_IMPL_API void ImGui_ImplGLUT_MouseFunc(int button, int state, int x, int y); // ~ MouseButtonFunc
IMGUI_IMPL_API void ImGui_ImplGLUT_MouseWheelFunc(int button, int dir, int x, int y); // ~ MouseWheelFunc
IMGUI_IMPL_API void ImGui_ImplGLUT_KeyboardFunc(unsigned char c, int x, int y); // ~ CharPressedFunc
IMGUI_IMPL_API void ImGui_ImplGLUT_KeyboardUpFunc(unsigned char c, int x, int y); // ~ CharReleasedFunc
IMGUI_IMPL_API void ImGui_ImplGLUT_SpecialFunc(int key, int x, int y); // ~ KeyPressedFunc
IMGUI_IMPL_API void ImGui_ImplGLUT_SpecialUpFunc(int key, int x, int y); // ~ KeyReleasedFunc

View File

@ -3,6 +3,8 @@
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'CIwTexture*' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp. // [X] Renderer: User texture binding. Use 'CIwTexture*' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp.
// Missing features:
// [ ] Renderer: Clipping rectangles are not honored.
// 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 are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
@ -10,6 +12,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2019-05-11: Inputs: Don't filter value from character callback before calling AddInputCharacter().
// 2018-11-30: Misc: Setting up io.BackendPlatformName/io.BackendRendererName so they can be displayed in the About Window. // 2018-11-30: Misc: Setting up io.BackendPlatformName/io.BackendRendererName so they can be displayed in the About Window.
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_Marmalade_RenderDrawData() in the .h file so you can call it yourself. // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_Marmalade_RenderDrawData() in the .h file so you can call it yourself.
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
@ -38,9 +41,9 @@ static ImVec2 g_RenderScale = ImVec2(1.0f,1.0f);
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
void ImGui_Marmalade_RenderDrawData(ImDrawData* draw_data) void ImGui_Marmalade_RenderDrawData(ImDrawData* draw_data)
{ {
// Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays) // Avoid rendering when minimized
ImGuiIO& io = ImGui::GetIO(); if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
draw_data->ScaleClipRects(io.DisplayFramebufferScale); return;
// Render command lists // Render command lists
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
@ -54,7 +57,7 @@ void ImGui_Marmalade_RenderDrawData(ImDrawData* draw_data)
for (int i = 0; i < nVert; i++) for (int i = 0; i < nVert; i++)
{ {
// TODO: optimize multiplication on gpu using vertex shader/projection matrix. // FIXME-OPT: optimize multiplication on GPU using vertex shader/projection matrix.
pVertStream[i].x = cmd_list->VtxBuffer[i].pos.x * g_RenderScale.x; pVertStream[i].x = cmd_list->VtxBuffer[i].pos.x * g_RenderScale.x;
pVertStream[i].y = cmd_list->VtxBuffer[i].pos.y * g_RenderScale.y; pVertStream[i].y = cmd_list->VtxBuffer[i].pos.y * g_RenderScale.y;
pUVStream[i].x = cmd_list->VtxBuffer[i].uv.x; pUVStream[i].x = cmd_list->VtxBuffer[i].uv.x;
@ -76,6 +79,7 @@ void ImGui_Marmalade_RenderDrawData(ImDrawData* draw_data)
} }
else else
{ {
// FIXME: Not honoring ClipRect fields.
CIwMaterial* pCurrentMaterial = IW_GX_ALLOC_MATERIAL(); CIwMaterial* pCurrentMaterial = IW_GX_ALLOC_MATERIAL();
pCurrentMaterial->SetShadeMode(CIwMaterial::SHADE_FLAT); pCurrentMaterial->SetShadeMode(CIwMaterial::SHADE_FLAT);
pCurrentMaterial->SetCullMode(CIwMaterial::CULL_NONE); pCurrentMaterial->SetCullMode(CIwMaterial::CULL_NONE);
@ -163,8 +167,7 @@ int32 ImGui_Marmalade_CharCallback(void* system_data, void* user_data)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
s3eKeyboardCharEvent* e = (s3eKeyboardCharEvent*)system_data; s3eKeyboardCharEvent* e = (s3eKeyboardCharEvent*)system_data;
if ((e->m_Char > 0 && e->m_Char < 0x10000)) io.AddInputCharacter((unsigned int)e->m_Char);
io.AddInputCharacter((unsigned short)e->m_Char);
return 0; return 0;
} }

View File

@ -3,6 +3,7 @@
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'MTLTexture' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp. // [X] Renderer: User texture binding. Use 'MTLTexture' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp.
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bits indices.
// 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 are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.

View File

@ -3,6 +3,7 @@
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'MTLTexture' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp. // [X] Renderer: User texture binding. Use 'MTLTexture' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp.
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bits indices.
// 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 are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
@ -10,6 +11,9 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2019-05-29: Metal: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
// 2019-04-30: Metal: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
// 2019-02-11: Metal: Projecting clipping rectangles correctly using draw_data->FramebufferScale to allow multi-viewports for retina display.
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. // 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
// 2018-07-05: Metal: Added new Metal backend implementation. // 2018-07-05: Metal: Added new Metal backend implementation.
@ -17,7 +21,7 @@
#include "imgui_impl_metal.h" #include "imgui_impl_metal.h"
#import <Metal/Metal.h> #import <Metal/Metal.h>
// #import <QuartzCore/CAMetalLayer.h> // Not suported in XCode 9.2. Maybe a macro to detect the SDK version can be used (something like #if MACOS_SDK >= 10.13 ...) // #import <QuartzCore/CAMetalLayer.h> // Not supported in XCode 9.2. Maybe a macro to detect the SDK version can be used (something like #if MACOS_SDK >= 10.13 ...)
#import <simd/simd.h> #import <simd/simd.h>
#pragma mark - Support classes #pragma mark - Support classes
@ -55,6 +59,12 @@
- (void)enqueueReusableBuffer:(MetalBuffer *)buffer; - (void)enqueueReusableBuffer:(MetalBuffer *)buffer;
- (id<MTLRenderPipelineState>)renderPipelineStateForFrameAndDevice:(id<MTLDevice>)device; - (id<MTLRenderPipelineState>)renderPipelineStateForFrameAndDevice:(id<MTLDevice>)device;
- (void)emptyRenderPipelineStateCache; - (void)emptyRenderPipelineStateCache;
- (void)setupRenderState:(ImDrawData *)drawData
commandBuffer:(id<MTLCommandBuffer>)commandBuffer
commandEncoder:(id<MTLRenderCommandEncoder>)commandEncoder
renderPipelineState:(id<MTLRenderPipelineState>)renderPipelineState
vertexBuffer:(MetalBuffer *)vertexBuffer
vertexBufferOffset:(size_t)vertexBufferOffset;
- (void)renderDrawData:(ImDrawData *)drawData - (void)renderDrawData:(ImDrawData *)drawData
commandBuffer:(id<MTLCommandBuffer>)commandBuffer commandBuffer:(id<MTLCommandBuffer>)commandBuffer
commandEncoder:(id<MTLRenderCommandEncoder>)commandEncoder; commandEncoder:(id<MTLRenderCommandEncoder>)commandEncoder;
@ -68,6 +78,7 @@ bool ImGui_ImplMetal_Init(id<MTLDevice> device)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.BackendRendererName = "imgui_impl_metal"; io.BackendRendererName = "imgui_impl_metal";
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
static dispatch_once_t onceToken; static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{ dispatch_once(&onceToken, ^{
@ -86,7 +97,7 @@ void ImGui_ImplMetal_Shutdown()
void ImGui_ImplMetal_NewFrame(MTLRenderPassDescriptor *renderPassDescriptor) void ImGui_ImplMetal_NewFrame(MTLRenderPassDescriptor *renderPassDescriptor)
{ {
IM_ASSERT(g_sharedMetalContext != nil && "No Metal context. Did you call ImGui_ImplMetal_Init?"); IM_ASSERT(g_sharedMetalContext != nil && "No Metal context. Did you call ImGui_ImplMetal_Init() ?");
g_sharedMetalContext.framebufferDescriptor = [[FramebufferDescriptor alloc] initWithRenderPassDescriptor:renderPassDescriptor]; g_sharedMetalContext.framebufferDescriptor = [[FramebufferDescriptor alloc] initWithRenderPassDescriptor:renderPassDescriptor];
} }
@ -282,7 +293,7 @@ void ImGui_ImplMetal_DestroyDeviceObjects()
- (_Nullable id<MTLRenderPipelineState>)renderPipelineStateForFrameAndDevice:(id<MTLDevice>)device - (_Nullable id<MTLRenderPipelineState>)renderPipelineStateForFrameAndDevice:(id<MTLDevice>)device
{ {
// Try to retrieve a render pipeline state that is compatible with the framebuffer config for this frame // Try to retrieve a render pipeline state that is compatible with the framebuffer config for this frame
// Thie hit rate for this cache should be very near 100%. // The hit rate for this cache should be very near 100%.
id<MTLRenderPipelineState> renderPipelineState = self.renderPipelineStateCache[self.framebufferDescriptor]; id<MTLRenderPipelineState> renderPipelineState = self.renderPipelineStateCache[self.framebufferDescriptor];
if (renderPipelineState == nil) if (renderPipelineState == nil)
@ -396,18 +407,13 @@ void ImGui_ImplMetal_DestroyDeviceObjects()
[self.renderPipelineStateCache removeAllObjects]; [self.renderPipelineStateCache removeAllObjects];
} }
- (void)renderDrawData:(ImDrawData *)drawData - (void)setupRenderState:(ImDrawData *)drawData
commandBuffer:(id<MTLCommandBuffer>)commandBuffer commandBuffer:(id<MTLCommandBuffer>)commandBuffer
commandEncoder:(id<MTLRenderCommandEncoder>)commandEncoder commandEncoder:(id<MTLRenderCommandEncoder>)commandEncoder
renderPipelineState:(id<MTLRenderPipelineState>)renderPipelineState
vertexBuffer:(MetalBuffer *)vertexBuffer
vertexBufferOffset:(size_t)vertexBufferOffset
{ {
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
ImGuiIO &io = ImGui::GetIO();
int fb_width = (int)(drawData->DisplaySize.x * io.DisplayFramebufferScale.x);
int fb_height = (int)(drawData->DisplaySize.y * io.DisplayFramebufferScale.y);
if (fb_width <= 0 || fb_height <= 0 || drawData->CmdListsCount == 0)
return;
drawData->ScaleClipRects(io.DisplayFramebufferScale);
[commandEncoder setCullMode:MTLCullModeNone]; [commandEncoder setCullMode:MTLCullModeNone];
[commandEncoder setDepthStencilState:g_sharedMetalContext.depthStencilState]; [commandEncoder setDepthStencilState:g_sharedMetalContext.depthStencilState];
@ -418,12 +424,13 @@ void ImGui_ImplMetal_DestroyDeviceObjects()
{ {
.originX = 0.0, .originX = 0.0,
.originY = 0.0, .originY = 0.0,
.width = double(fb_width), .width = (double)(drawData->DisplaySize.x * drawData->FramebufferScale.x),
.height = double(fb_height), .height = (double)(drawData->DisplaySize.y * drawData->FramebufferScale.y),
.znear = 0.0, .znear = 0.0,
.zfar = 1.0 .zfar = 1.0
}; };
[commandEncoder setViewport:viewport]; [commandEncoder setViewport:viewport];
float L = drawData->DisplayPos.x; float L = drawData->DisplayPos.x;
float R = drawData->DisplayPos.x + drawData->DisplaySize.x; float R = drawData->DisplayPos.x + drawData->DisplaySize.x;
float T = drawData->DisplayPos.y; float T = drawData->DisplayPos.y;
@ -437,71 +444,93 @@ void ImGui_ImplMetal_DestroyDeviceObjects()
{ 0.0f, 0.0f, 1/(F-N), 0.0f }, { 0.0f, 0.0f, 1/(F-N), 0.0f },
{ (R+L)/(L-R), (T+B)/(B-T), N/(F-N), 1.0f }, { (R+L)/(L-R), (T+B)/(B-T), N/(F-N), 1.0f },
}; };
[commandEncoder setVertexBytes:&ortho_projection length:sizeof(ortho_projection) atIndex:1]; [commandEncoder setVertexBytes:&ortho_projection length:sizeof(ortho_projection) atIndex:1];
size_t vertexBufferLength = 0;
size_t indexBufferLength = 0;
for (int n = 0; n < drawData->CmdListsCount; n++)
{
const ImDrawList* cmd_list = drawData->CmdLists[n];
vertexBufferLength += cmd_list->VtxBuffer.Size * sizeof(ImDrawVert);
indexBufferLength += cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx);
}
MetalBuffer *vertexBuffer = [self dequeueReusableBufferOfLength:vertexBufferLength device:commandBuffer.device];
MetalBuffer *indexBuffer = [self dequeueReusableBufferOfLength:indexBufferLength device:commandBuffer.device];
id<MTLRenderPipelineState> renderPipelineState = [self renderPipelineStateForFrameAndDevice:commandBuffer.device];
[commandEncoder setRenderPipelineState:renderPipelineState]; [commandEncoder setRenderPipelineState:renderPipelineState];
[commandEncoder setVertexBuffer:vertexBuffer.buffer offset:0 atIndex:0]; [commandEncoder setVertexBuffer:vertexBuffer.buffer offset:0 atIndex:0];
[commandEncoder setVertexBufferOffset:vertexBufferOffset atIndex:0];
}
- (void)renderDrawData:(ImDrawData *)drawData
commandBuffer:(id<MTLCommandBuffer>)commandBuffer
commandEncoder:(id<MTLRenderCommandEncoder>)commandEncoder
{
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
int fb_width = (int)(drawData->DisplaySize.x * drawData->FramebufferScale.x);
int fb_height = (int)(drawData->DisplaySize.y * drawData->FramebufferScale.y);
if (fb_width <= 0 || fb_height <= 0 || drawData->CmdListsCount == 0)
return;
id<MTLRenderPipelineState> renderPipelineState = [self renderPipelineStateForFrameAndDevice:commandBuffer.device];
size_t vertexBufferLength = drawData->TotalVtxCount * sizeof(ImDrawVert);
size_t indexBufferLength = drawData->TotalIdxCount * sizeof(ImDrawIdx);
MetalBuffer* vertexBuffer = [self dequeueReusableBufferOfLength:vertexBufferLength device:commandBuffer.device];
MetalBuffer* indexBuffer = [self dequeueReusableBufferOfLength:indexBufferLength device:commandBuffer.device];
[self setupRenderState:drawData commandBuffer:commandBuffer commandEncoder:commandEncoder renderPipelineState:renderPipelineState vertexBuffer:vertexBuffer vertexBufferOffset:0];
// Will project scissor/clipping rectangles into framebuffer space
ImVec2 clip_off = drawData->DisplayPos; // (0,0) unless using multi-viewports
ImVec2 clip_scale = drawData->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
// Render command lists
size_t vertexBufferOffset = 0; size_t vertexBufferOffset = 0;
size_t indexBufferOffset = 0; size_t indexBufferOffset = 0;
ImVec2 pos = drawData->DisplayPos;
for (int n = 0; n < drawData->CmdListsCount; n++) for (int n = 0; n < drawData->CmdListsCount; n++)
{ {
const ImDrawList* cmd_list = drawData->CmdLists[n]; const ImDrawList* cmd_list = drawData->CmdLists[n];
ImDrawIdx idx_buffer_offset = 0;
memcpy((char *)vertexBuffer.buffer.contents + vertexBufferOffset, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert)); memcpy((char *)vertexBuffer.buffer.contents + vertexBufferOffset, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
memcpy((char *)indexBuffer.buffer.contents + indexBufferOffset, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); memcpy((char *)indexBuffer.buffer.contents + indexBufferOffset, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
[commandEncoder setVertexBufferOffset:vertexBufferOffset atIndex:0];
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{ {
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback) if (pcmd->UserCallback)
{ {
// User callback (registered via ImDrawList::AddCallback) // User callback, registered via ImDrawList::AddCallback()
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
[self setupRenderState:drawData commandBuffer:commandBuffer commandEncoder:commandEncoder renderPipelineState:renderPipelineState vertexBuffer:vertexBuffer vertexBufferOffset:vertexBufferOffset];
else
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(cmd_list, pcmd);
} }
else else
{ {
ImVec4 clip_rect = ImVec4(pcmd->ClipRect.x - pos.x, pcmd->ClipRect.y - pos.y, pcmd->ClipRect.z - pos.x, pcmd->ClipRect.w - pos.y); // Project scissor/clipping rectangles into framebuffer space
ImVec4 clip_rect;
clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x;
clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y;
clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x;
clip_rect.w = (pcmd->ClipRect.w - clip_off.y) * clip_scale.y;
if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f) if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f)
{ {
// Apply scissor/clipping rectangle // Apply scissor/clipping rectangle
MTLScissorRect scissorRect = { .x = NSUInteger(clip_rect.x), MTLScissorRect scissorRect =
{
.x = NSUInteger(clip_rect.x),
.y = NSUInteger(clip_rect.y), .y = NSUInteger(clip_rect.y),
.width = NSUInteger(clip_rect.z - clip_rect.x), .width = NSUInteger(clip_rect.z - clip_rect.x),
.height = NSUInteger(clip_rect.w - clip_rect.y) }; .height = NSUInteger(clip_rect.w - clip_rect.y)
};
[commandEncoder setScissorRect:scissorRect]; [commandEncoder setScissorRect:scissorRect];
// Bind texture, Draw // Bind texture, Draw
if (pcmd->TextureId != NULL) if (pcmd->TextureId != NULL)
[commandEncoder setFragmentTexture:(__bridge id<MTLTexture>)(pcmd->TextureId) atIndex:0]; [commandEncoder setFragmentTexture:(__bridge id<MTLTexture>)(pcmd->TextureId) atIndex:0];
[commandEncoder setVertexBufferOffset:(vertexBufferOffset + pcmd->VtxOffset * sizeof(ImDrawVert)) atIndex:0];
[commandEncoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle [commandEncoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle
indexCount:pcmd->ElemCount indexCount:pcmd->ElemCount
indexType:sizeof(ImDrawIdx) == 2 ? MTLIndexTypeUInt16 : MTLIndexTypeUInt32 indexType:sizeof(ImDrawIdx) == 2 ? MTLIndexTypeUInt16 : MTLIndexTypeUInt32
indexBuffer:indexBuffer.buffer indexBuffer:indexBuffer.buffer
indexBufferOffset:indexBufferOffset + idx_buffer_offset]; indexBufferOffset:indexBufferOffset + pcmd->IdxOffset * sizeof(ImDrawIdx)];
} }
} }
idx_buffer_offset += pcmd->ElemCount * sizeof(ImDrawIdx);
} }
vertexBufferOffset += cmd_list->VtxBuffer.Size * sizeof(ImDrawVert); vertexBufferOffset += cmd_list->VtxBuffer.Size * sizeof(ImDrawVert);

View File

@ -18,6 +18,8 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2019-04-30: OpenGL: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
// 2019-02-11: OpenGL: Projecting clipping rectangles correctly using draw_data->FramebufferScale to allow multi-viewports for retina display.
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. // 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
// 2018-08-03: OpenGL: Disabling/restoring GL_LIGHTING and GL_COLOR_MATERIAL to increase compatibility with legacy OpenGL applications. // 2018-08-03: OpenGL: Disabling/restoring GL_LIGHTING and GL_COLOR_MATERIAL to increase compatibility with legacy OpenGL applications.
// 2018-06-08: Misc: Extracted imgui_impl_opengl2.cpp/.h away from the old combined GLFW/SDL+OpenGL2 examples. // 2018-06-08: Misc: Extracted imgui_impl_opengl2.cpp/.h away from the old combined GLFW/SDL+OpenGL2 examples.
@ -43,6 +45,7 @@
#define WINGDIAPI __declspec(dllimport) // Some Windows OpenGL headers need this #define WINGDIAPI __declspec(dllimport) // Some Windows OpenGL headers need this
#endif #endif
#if defined(__APPLE__) #if defined(__APPLE__)
#define GL_SILENCE_DEPRECATION
#include <OpenGL/gl.h> #include <OpenGL/gl.h>
#else #else
#include <GL/gl.h> #include <GL/gl.h>
@ -54,6 +57,7 @@ static GLuint g_FontTexture = 0;
// Functions // Functions
bool ImGui_ImplOpenGL2_Init() bool ImGui_ImplOpenGL2_Init()
{ {
// Setup back-end capabilities flags
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.BackendRendererName = "imgui_impl_opengl2"; io.BackendRendererName = "imgui_impl_opengl2";
return true; return true;
@ -70,26 +74,9 @@ void ImGui_ImplOpenGL2_NewFrame()
ImGui_ImplOpenGL2_CreateDeviceObjects(); ImGui_ImplOpenGL2_CreateDeviceObjects();
} }
// OpenGL2 Render function. static void ImGui_ImplOpenGL2_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height)
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so.
void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
{ {
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
ImGuiIO& io = ImGui::GetIO();
int fb_width = (int)(draw_data->DisplaySize.x * io.DisplayFramebufferScale.x);
int fb_height = (int)(draw_data->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!
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers, polygon fill. // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers, polygon fill.
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
@ -102,10 +89,17 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_COLOR_ARRAY);
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
//glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound
// If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!),
// you may need to backup/reset/restore current shader using the lines below. DO NOT MODIFY THIS FILE! Add the code in your calling function:
// GLint last_program;
// glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
// glUseProgram(0);
// ImGui_ImplOpenGL2_RenderDrawData(...);
// glUseProgram(last_program)
// Setup viewport, orthographic projection matrix // Setup viewport, orthographic projection matrix
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayMin is typically (0,0) for single viewport apps. // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height);
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glPushMatrix(); glPushMatrix();
@ -114,9 +108,34 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glPushMatrix(); glPushMatrix();
glLoadIdentity(); glLoadIdentity();
}
// OpenGL2 Render function.
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so.
void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
{
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
if (fb_width == 0 || fb_height == 0)
return;
// Backup GL state
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT);
// Setup desired GL state
ImGui_ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height);
// Will project scissor/clipping rectangles into framebuffer space
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
// Render command lists // Render command lists
ImVec2 pos = draw_data->DisplayPos;
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];
@ -131,12 +150,22 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback) if (pcmd->UserCallback)
{ {
// User callback (registered via ImDrawList::AddCallback) // User callback, registered via ImDrawList::AddCallback()
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height);
else
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(cmd_list, pcmd);
} }
else else
{ {
ImVec4 clip_rect = ImVec4(pcmd->ClipRect.x - pos.x, pcmd->ClipRect.y - pos.y, pcmd->ClipRect.z - pos.x, pcmd->ClipRect.w - pos.y); // Project scissor/clipping rectangles into framebuffer space
ImVec4 clip_rect;
clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x;
clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y;
clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x;
clip_rect.w = (pcmd->ClipRect.w - clip_off.y) * clip_scale.y;
if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f) if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f)
{ {
// Apply scissor/clipping rectangle // Apply scissor/clipping rectangle
@ -151,7 +180,7 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
} }
} }
// Restore modified state // Restore modified GL state
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);

View File

@ -1,9 +1,11 @@
// dear imgui: Renderer for OpenGL3 / OpenGL ES2 / OpenGL ES3 (modern OpenGL with shaders / programmatic pipeline) // dear imgui: Renderer for modern OpenGL with shaders / programmatic pipeline
// - Desktop GL: 3.x 4.x
// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0)
// This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..) // This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..)
// (Note: We are using GL3W as a helper library to access OpenGL functions since there is no standard header to access modern OpenGL functions easily. Alternatives are GLEW, Glad, etc..)
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID in imgui.cpp. // [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID in imgui.cpp.
// [x] Renderer: Desktop GL only: Support for large meshes (64k+ vertices) with 16-bits indices.
// 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 are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
@ -11,8 +13,16 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2019-05-29: OpenGL: Desktop GL only: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
// 2019-04-30: OpenGL: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
// 2019-03-29: OpenGL: Not calling glBindBuffer more than necessary in the render loop.
// 2019-03-15: OpenGL: Added a dummy GL call + comments in ImGui_ImplOpenGL3_Init() to detect uninitialized GL function loaders early.
// 2019-03-03: OpenGL: Fix support for ES 2.0 (WebGL 1.0).
// 2019-02-20: OpenGL: Fix for OSX not supporting OpenGL 4.5, we don't try to read GL_CLIP_ORIGIN even if defined by the headers/loader.
// 2019-02-11: OpenGL: Projecting clipping rectangles correctly using draw_data->FramebufferScale to allow multi-viewports for retina display.
// 2019-02-01: OpenGL: Using GLSL 410 shaders for any version over 410 (e.g. 430, 450).
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. // 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
// 2018-11-13: OpenGL: Support for GL 4.5's glClipControl(GL_UPPER_LEFT). // 2018-11-13: OpenGL: Support for GL 4.5's glClipControl(GL_UPPER_LEFT) / GL_CLIP_ORIGIN.
// 2018-08-29: OpenGL: Added support for more OpenGL loaders: glew and glad, with comments indicative that any loader can be used. // 2018-08-29: OpenGL: Added support for more OpenGL loaders: glew and glad, with comments indicative that any loader can be used.
// 2018-08-09: OpenGL: Default to OpenGL ES 3 on iOS and Android. GLSL version default to "#version 300 ES". // 2018-08-09: OpenGL: Default to OpenGL ES 3 on iOS and Android. GLSL version default to "#version 300 ES".
// 2018-07-30: OpenGL: Support for GLSL 300 ES and 410 core. Fixes for Emscripten compilation. // 2018-07-30: OpenGL: Support for GLSL 300 ES and 410 core. Fixes for Emscripten compilation.
@ -36,17 +46,17 @@
// version version string // version version string
//---------------------------------------- //----------------------------------------
// 2.0 110 "#version 110" // 2.0 110 "#version 110"
// 2.1 120 // 2.1 120 "#version 120"
// 3.0 130 // 3.0 130 "#version 130"
// 3.1 140 // 3.1 140 "#version 140"
// 3.2 150 "#version 150" // 3.2 150 "#version 150"
// 3.3 330 // 3.3 330 "#version 330 core"
// 4.0 400 // 4.0 400 "#version 400 core"
// 4.1 410 "#version 410 core" // 4.1 410 "#version 410 core"
// 4.2 420 // 4.2 420 "#version 410 core"
// 4.3 430 // 4.3 430 "#version 430 core"
// ES 2.0 100 "#version 100" // ES 2.0 100 "#version 100" = WebGL 1.0
// ES 3.0 300 "#version 300 es" // ES 3.0 300 "#version 300 es" = WebGL 2.0
//---------------------------------------- //----------------------------------------
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
@ -65,47 +75,65 @@
#include "TargetConditionals.h" #include "TargetConditionals.h"
#endif #endif
// iOS, Android and Emscripten can use GL ES 3 // Auto-detect GL version
// Call ImGui_ImplOpenGL3_Init() with "#version 300 es" #if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3)
#if (defined(__APPLE__) && TARGET_OS_IOS) || (defined(__ANDROID__)) || (defined(__EMSCRIPTEN__)) #if (defined(__APPLE__) && TARGET_OS_IOS) || (defined(__ANDROID__))
#define USE_GL_ES3 #define IMGUI_IMPL_OPENGL_ES3 // iOS, Android -> GL ES 3, "#version 300 es"
#elif defined(__EMSCRIPTEN__)
#define IMGUI_IMPL_OPENGL_ES2 // Emscripten -> GL ES 2, "#version 100"
#endif
#endif #endif
#ifdef USE_GL_ES3 #if defined(IMGUI_IMPL_OPENGL_ES2)
// OpenGL ES 3 #include <GLES2/gl2.h>
#elif defined(IMGUI_IMPL_OPENGL_ES3)
#include <GLES3/gl3.h> // Use GL ES 3 #include <GLES3/gl3.h> // Use GL ES 3
#else #else
// Regular OpenGL // About Desktop OpenGL function loaders:
// About OpenGL function loaders: modern OpenGL doesn't have a standard header file and requires individual function pointers to be loaded manually. // Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers.
// Helper libraries are often used for this purpose! Here we are supporting a few common ones: gl3w, glew, glad. // Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad).
// You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own. // You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own.
#if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) #if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W)
#include <GL/gl3w.h> #include <GL/gl3w.h> // Needs to be initialized with gl3wInit() in user's code
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW)
#include <GL/glew.h> #include <GL/glew.h> // Needs to be initialized with glewInit() in user's code
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
#include <glad/glad.h> #include <glad/glad.h> // Needs to be initialized with gladLoadGL() in user's code
#else #else
#include IMGUI_IMPL_OPENGL_LOADER_CUSTOM #include IMGUI_IMPL_OPENGL_LOADER_CUSTOM
#endif #endif
#endif #endif
// Desktop GL has glDrawElementsBaseVertex() which GL ES and WebGL don't have.
#if defined(IMGUI_IMPL_OPENGL_ES2) || defined(IMGUI_IMPL_OPENGL_ES3)
#define IMGUI_IMPL_OPENGL_HAS_DRAW_WITH_BASE_VERTEX 0
#else
#define IMGUI_IMPL_OPENGL_HAS_DRAW_WITH_BASE_VERTEX 1
#endif
// OpenGL Data // OpenGL Data
static char g_GlslVersionString[32] = ""; static char g_GlslVersionString[32] = "";
static GLuint g_FontTexture = 0; static GLuint g_FontTexture = 0;
static GLuint g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; static GLuint g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0;
static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; // Uniforms location
static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; static int g_AttribLocationVtxPos = 0, g_AttribLocationVtxUV = 0, g_AttribLocationVtxColor = 0; // Vertex attributes location
static unsigned int g_VboHandle = 0, g_ElementsHandle = 0; static unsigned int g_VboHandle = 0, g_ElementsHandle = 0;
// Functions // Functions
bool ImGui_ImplOpenGL3_Init(const char* glsl_version) bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
{ {
// Setup back-end capabilities flags
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.BackendRendererName = "imgui_impl_opengl3"; io.BackendRendererName = "imgui_impl_opengl3";
#if IMGUI_IMPL_OPENGL_HAS_DRAW_WITH_BASE_VERTEX
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
#endif
// Store GLSL version string so we can refer to it later in case we recreate shaders. Note: GLSL version is NOT the same as GL version. Leave this to NULL if unsure. // Store GLSL version string so we can refer to it later in case we recreate shaders. Note: GLSL version is NOT the same as GL version. Leave this to NULL if unsure.
#ifdef USE_GL_ES3 #if defined(IMGUI_IMPL_OPENGL_ES2)
if (glsl_version == NULL)
glsl_version = "#version 100";
#elif defined(IMGUI_IMPL_OPENGL_ES3)
if (glsl_version == NULL) if (glsl_version == NULL)
glsl_version = "#version 300 es"; glsl_version = "#version 300 es";
#else #else
@ -116,6 +144,12 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
strcpy(g_GlslVersionString, glsl_version); strcpy(g_GlslVersionString, glsl_version);
strcat(g_GlslVersionString, "\n"); strcat(g_GlslVersionString, "\n");
// Make a dummy GL call (we don't actually need the result)
// IF YOU GET A CRASH HERE: it probably means that you haven't initialized the OpenGL function loader used by this code.
// Desktop OpenGL 3/4 need a function loader. See the IMGUI_IMPL_OPENGL_LOADER_xxx explanation above.
GLint current_texture;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
return true; return true;
} }
@ -130,51 +164,8 @@ void ImGui_ImplOpenGL3_NewFrame()
ImGui_ImplOpenGL3_CreateDeviceObjects(); ImGui_ImplOpenGL3_CreateDeviceObjects();
} }
// OpenGL3 Render function. static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height, GLuint vertex_array_object)
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so.
void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
{ {
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
ImGuiIO& io = ImGui::GetIO();
int fb_width = (int)(draw_data->DisplaySize.x * io.DisplayFramebufferScale.x);
int fb_height = (int)(draw_data->DisplaySize.y * io.DisplayFramebufferScale.y);
if (fb_width <= 0 || fb_height <= 0)
return;
draw_data->ScaleClipRects(io.DisplayFramebufferScale);
// Backup GL state
GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&last_active_texture);
glActiveTexture(GL_TEXTURE0);
GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
#ifdef GL_SAMPLER_BINDING
GLint last_sampler; glGetIntegerv(GL_SAMPLER_BINDING, &last_sampler);
#endif
GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
#ifdef GL_POLYGON_MODE
GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
#endif
GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, (GLint*)&last_blend_src_rgb);
GLenum last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, (GLint*)&last_blend_dst_rgb);
GLenum last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint*)&last_blend_src_alpha);
GLenum last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint*)&last_blend_dst_alpha);
GLenum last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint*)&last_blend_equation_rgb);
GLenum last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint*)&last_blend_equation_alpha);
GLboolean last_enable_blend = glIsEnabled(GL_BLEND);
GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE);
GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST);
GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
bool clip_origin_lower_left = true;
#ifdef GL_CLIP_ORIGIN
GLenum last_clip_origin = 0; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)&last_clip_origin); // Support for GL 4.5's glClipControl(GL_UPPER_LEFT)
if (last_clip_origin == GL_UPPER_LEFT)
clip_origin_lower_left = false;
#endif
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD); glBlendEquation(GL_FUNC_ADD);
@ -187,7 +178,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
#endif #endif
// Setup viewport, orthographic projection matrix // Setup viewport, orthographic projection matrix
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayMin is typically (0,0) for single viewport apps. // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height);
float L = draw_data->DisplayPos.x; float L = draw_data->DisplayPos.x;
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
@ -206,60 +197,135 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
#ifdef GL_SAMPLER_BINDING #ifdef GL_SAMPLER_BINDING
glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise. glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise.
#endif #endif
// Recreate the VAO every time
// (This is to easily allow multiple GL contexts. VAO are not shared among GL contexts, and we don't track creation/deletion of windows so we don't have an obvious key to use to cache them.)
GLuint vao_handle = 0;
glGenVertexArrays(1, &vao_handle);
glBindVertexArray(vao_handle);
glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
glEnableVertexAttribArray(g_AttribLocationPosition);
glEnableVertexAttribArray(g_AttribLocationUV);
glEnableVertexAttribArray(g_AttribLocationColor);
glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos));
glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv));
glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col));
// Draw (void)vertex_array_object;
ImVec2 pos = draw_data->DisplayPos; #ifndef IMGUI_IMPL_OPENGL_ES2
glBindVertexArray(vertex_array_object);
#endif
// Bind vertex/index buffers and setup attributes for ImDrawVert
glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle);
glEnableVertexAttribArray(g_AttribLocationVtxPos);
glEnableVertexAttribArray(g_AttribLocationVtxUV);
glEnableVertexAttribArray(g_AttribLocationVtxColor);
glVertexAttribPointer(g_AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos));
glVertexAttribPointer(g_AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv));
glVertexAttribPointer(g_AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col));
}
// OpenGL3 Render function.
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so.
void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
{
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
if (fb_width <= 0 || fb_height <= 0)
return;
// Backup GL state
GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&last_active_texture);
glActiveTexture(GL_TEXTURE0);
GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
#ifdef GL_SAMPLER_BINDING
GLint last_sampler; glGetIntegerv(GL_SAMPLER_BINDING, &last_sampler);
#endif
GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
#ifndef IMGUI_IMPL_OPENGL_ES2
GLint last_vertex_array_object; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array_object);
#endif
#ifdef GL_POLYGON_MODE
GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
#endif
GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, (GLint*)&last_blend_src_rgb);
GLenum last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, (GLint*)&last_blend_dst_rgb);
GLenum last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint*)&last_blend_src_alpha);
GLenum last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint*)&last_blend_dst_alpha);
GLenum last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint*)&last_blend_equation_rgb);
GLenum last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint*)&last_blend_equation_alpha);
GLboolean last_enable_blend = glIsEnabled(GL_BLEND);
GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE);
GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST);
GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
bool clip_origin_lower_left = true;
#if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__)
GLenum last_clip_origin = 0; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)&last_clip_origin); // Support for GL 4.5's glClipControl(GL_UPPER_LEFT)
if (last_clip_origin == GL_UPPER_LEFT)
clip_origin_lower_left = false;
#endif
// Setup desired GL state
// Recreate the VAO every time (this is to easily allow multiple GL contexts to be rendered to. VAO are not shared among GL contexts)
// The renderer would actually work without any VAO bound, but then our VertexAttrib calls would overwrite the default one currently bound.
GLuint vertex_array_object = 0;
#ifndef IMGUI_IMPL_OPENGL_ES2
glGenVertexArrays(1, &vertex_array_object);
#endif
ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object);
// Will project scissor/clipping rectangles into framebuffer space
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
// Render command lists
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];
const ImDrawIdx* idx_buffer_offset = 0;
glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); // Upload vertex/index buffers
glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW); glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx), (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx), (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW);
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{ {
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback) if (pcmd->UserCallback != NULL)
{ {
// User callback (registered via ImDrawList::AddCallback) // User callback, registered via ImDrawList::AddCallback()
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object);
else
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(cmd_list, pcmd);
} }
else else
{ {
ImVec4 clip_rect = ImVec4(pcmd->ClipRect.x - pos.x, pcmd->ClipRect.y - pos.y, pcmd->ClipRect.z - pos.x, pcmd->ClipRect.w - pos.y); // Project scissor/clipping rectangles into framebuffer space
ImVec4 clip_rect;
clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x;
clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y;
clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x;
clip_rect.w = (pcmd->ClipRect.w - clip_off.y) * clip_scale.y;
if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f) if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f)
{ {
// Apply scissor/clipping rectangle // Apply scissor/clipping rectangle
if (clip_origin_lower_left) if (clip_origin_lower_left)
glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y)); glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y));
else else
glScissor((int)clip_rect.x, (int)clip_rect.y, (int)clip_rect.z, (int)clip_rect.w); // Support for GL 4.5's glClipControl(GL_UPPER_LEFT) glScissor((int)clip_rect.x, (int)clip_rect.y, (int)clip_rect.z, (int)clip_rect.w); // Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT)
// Bind texture, Draw // Bind texture, Draw
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId);
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset); #if IMGUI_IMPL_OPENGL_HAS_DRAW_WITH_BASE_VERTEX
glDrawElementsBaseVertex(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)), (GLint)pcmd->VtxOffset);
#else
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)));
#endif
} }
} }
idx_buffer_offset += pcmd->ElemCount;
} }
} }
glDeleteVertexArrays(1, &vao_handle);
// Destroy the temporary VAO
#ifndef IMGUI_IMPL_OPENGL_ES2
glDeleteVertexArrays(1, &vertex_array_object);
#endif
// Restore modified GL state // Restore modified GL state
glUseProgram(last_program); glUseProgram(last_program);
@ -268,7 +334,9 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
glBindSampler(0, last_sampler); glBindSampler(0, last_sampler);
#endif #endif
glActiveTexture(last_active_texture); glActiveTexture(last_active_texture);
glBindVertexArray(last_vertex_array); #ifndef IMGUI_IMPL_OPENGL_ES2
glBindVertexArray(last_vertex_array_object);
#endif
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha);
glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha); glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha);
@ -298,7 +366,9 @@ bool ImGui_ImplOpenGL3_CreateFontsTexture()
glBindTexture(GL_TEXTURE_2D, g_FontTexture); glBindTexture(GL_TEXTURE_2D, g_FontTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
#ifdef GL_UNPACK_ROW_LENGTH
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
#endif
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
// Store our identifier // Store our identifier
@ -329,7 +399,7 @@ static bool CheckShader(GLuint handle, const char* desc)
glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &log_length); glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &log_length);
if ((GLboolean)status == GL_FALSE) if ((GLboolean)status == GL_FALSE)
fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile %s!\n", desc); fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile %s!\n", desc);
if (log_length > 0) if (log_length > 1)
{ {
ImVector<char> buf; ImVector<char> buf;
buf.resize((int)(log_length + 1)); buf.resize((int)(log_length + 1));
@ -347,7 +417,7 @@ static bool CheckProgram(GLuint handle, const char* desc)
glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &log_length); glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &log_length);
if ((GLboolean)status == GL_FALSE) if ((GLboolean)status == GL_FALSE)
fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to link %s! (with GLSL '%s')\n", desc, g_GlslVersionString); fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to link %s! (with GLSL '%s')\n", desc, g_GlslVersionString);
if (log_length > 0) if (log_length > 1)
{ {
ImVector<char> buf; ImVector<char> buf;
buf.resize((int)(log_length + 1)); buf.resize((int)(log_length + 1));
@ -360,10 +430,13 @@ static bool CheckProgram(GLuint handle, const char* desc)
bool ImGui_ImplOpenGL3_CreateDeviceObjects() bool ImGui_ImplOpenGL3_CreateDeviceObjects()
{ {
// Backup GL state // Backup GL state
GLint last_texture, last_array_buffer, last_vertex_array; GLint last_texture, last_array_buffer;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
#ifndef IMGUI_IMPL_OPENGL_ES2
GLint last_vertex_array;
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
#endif
// Parse GLSL version string // Parse GLSL version string
int glsl_version = 130; int glsl_version = 130;
@ -477,7 +550,7 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects()
vertex_shader = vertex_shader_glsl_120; vertex_shader = vertex_shader_glsl_120;
fragment_shader = fragment_shader_glsl_120; fragment_shader = fragment_shader_glsl_120;
} }
else if (glsl_version == 410) else if (glsl_version >= 410)
{ {
vertex_shader = vertex_shader_glsl_410_core; vertex_shader = vertex_shader_glsl_410_core;
fragment_shader = fragment_shader_glsl_410_core; fragment_shader = fragment_shader_glsl_410_core;
@ -514,9 +587,9 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects()
g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture");
g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx");
g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); g_AttribLocationVtxPos = glGetAttribLocation(g_ShaderHandle, "Position");
g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); g_AttribLocationVtxUV = glGetAttribLocation(g_ShaderHandle, "UV");
g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); g_AttribLocationVtxColor = glGetAttribLocation(g_ShaderHandle, "Color");
// Create buffers // Create buffers
glGenBuffers(1, &g_VboHandle); glGenBuffers(1, &g_VboHandle);
@ -527,7 +600,9 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects()
// Restore modified GL state // Restore modified GL state
glBindTexture(GL_TEXTURE_2D, last_texture); glBindTexture(GL_TEXTURE_2D, last_texture);
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
#ifndef IMGUI_IMPL_OPENGL_ES2
glBindVertexArray(last_vertex_array); glBindVertexArray(last_vertex_array);
#endif
return true; return true;
} }

View File

@ -1,17 +1,19 @@
// dear imgui: Renderer for OpenGL3 / OpenGL ES2 / OpenGL ES3 (modern OpenGL with shaders / programmatic pipeline) // dear imgui: Renderer for modern OpenGL with shaders / programmatic pipeline
// - Desktop GL: 3.x 4.x
// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0)
// This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..) // This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..)
// (Note: We are using GL3W as a helper library to access OpenGL functions since there is no standard header to access modern OpenGL functions easily. Alternatives are GLEW, Glad, etc..)
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID in imgui.cpp. // [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID in imgui.cpp.
// [x] Renderer: Desktop GL only: Support for large meshes (64k+ vertices) with 16-bits indices.
// 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 are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
// https://github.com/ocornut/imgui // https://github.com/ocornut/imgui
// About OpenGL function loaders: // About Desktop OpenGL function loaders:
// About OpenGL function loaders: modern OpenGL doesn't have a standard header file and requires individual function pointers to be loaded manually. // Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers.
// Helper libraries are often used for this purpose! Here we are supporting a few common ones: gl3w, glew, glad. // Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad).
// You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own. // You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own.
// About GLSL version: // About GLSL version:
@ -21,7 +23,11 @@
#pragma once #pragma once
// Set default OpenGL loader to be gl3w // Specific OpenGL versions
//#define IMGUI_IMPL_OPENGL_ES2 // Auto-detected on Emscripten
//#define IMGUI_IMPL_OPENGL_ES3 // Auto-detected on iOS/Android
// Set default OpenGL3 loader to be gl3w
#if !defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) \ #if !defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) \
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) \ && !defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) \
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) \ && !defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) \

View File

@ -1,10 +1,12 @@
// dear imgui: Platform Binding for OSX / Cocoa // dear imgui: Platform Binding for OSX / Cocoa
// This needs to be used along with a Renderer (e.g. OpenGL2, OpenGL3, Vulkan, Metal..) // This needs to be used along with a Renderer (e.g. OpenGL2, OpenGL3, Vulkan, Metal..)
// [BETA] Beta bindings, not well tested. If you want a portable application, prefer using the Glfw or SDL platform bindings on Mac. // [ALPHA] Early bindings, not well tested. If you want a portable application, prefer using the GLFW or SDL platform bindings on Mac.
// Implemented features:
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this back-end).
// Issues: // Issues:
// [ ] Platform: Keys are all generally very broken. Best using [event keycode] and not [event characters].. // [ ] Platform: Keys are all generally very broken. Best using [event keycode] and not [event characters]..
// [ ] Platform: Mouse cursor shapes and visibility are not supported (see end of https://github.com/glfw/glfw/issues/427)
@class NSEvent; @class NSEvent;
@class NSView; @class NSView;

View File

@ -1,10 +1,12 @@
// dear imgui: Platform Binding for OSX / Cocoa // dear imgui: Platform Binding for OSX / Cocoa
// This needs to be used along with a Renderer (e.g. OpenGL2, OpenGL3, Vulkan, Metal..) // This needs to be used along with a Renderer (e.g. OpenGL2, OpenGL3, Vulkan, Metal..)
// [BETA] Beta bindings, not well tested. If you want a portable application, prefer using the Glfw or SDL platform bindings on Mac. // [ALPHA] Early bindings, not well tested. If you want a portable application, prefer using the GLFW or SDL platform bindings on Mac.
// Implemented features:
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this back-end).
// Issues: // Issues:
// [ ] Platform: Keys are all generally very broken. Best using [event keycode] and not [event characters].. // [ ] Platform: Keys are all generally very broken. Best using [event keycode] and not [event characters]..
// [ ] Platform: Mouse cursor shapes and visibility are not supported (see end of https://github.com/glfw/glfw/issues/427)
#include "imgui.h" #include "imgui.h"
#include "imgui_impl_osx.h" #include "imgui_impl_osx.h"
@ -12,11 +14,24 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2019-05-28: Inputs: Added mouse cursor shape and visibility support.
// 2019-05-18: Misc: Removed clipboard handlers as they are now supported by core imgui.cpp.
// 2019-05-11: Inputs: Don't filter character values before calling AddInputCharacter() apart from 0xF700..0xFFFF range.
// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window. // 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window.
// 2018-07-07: Initial version. // 2018-07-07: Initial version.
// Data // Data
static CFAbsoluteTime g_Time = 0.0; static CFAbsoluteTime g_Time = 0.0;
static NSCursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = { 0 };
static bool g_MouseCursorHidden = false;
// Undocumented methods for creating cursors.
@interface NSCursor()
+ (id)_windowResizeNorthWestSouthEastCursor;
+ (id)_windowResizeNorthEastSouthWestCursor;
+ (id)_windowResizeNorthSouthCursor;
+ (id)_windowResizeEastWestCursor;
@end
// Functions // Functions
bool ImGui_ImplOSX_Init() bool ImGui_ImplOSX_Init()
@ -24,7 +39,7 @@ bool ImGui_ImplOSX_Init()
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
// Setup back-end capabilities flags // Setup back-end capabilities flags
//io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
//io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) //io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
//io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional) //io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
//io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can set io.MouseHoveredViewport correctly (optional, not easy) //io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can set io.MouseHoveredViewport correctly (optional, not easy)
@ -54,31 +69,19 @@ bool ImGui_ImplOSX_Init()
io.KeyMap[ImGuiKey_Y] = 'Y'; io.KeyMap[ImGuiKey_Y] = 'Y';
io.KeyMap[ImGuiKey_Z] = 'Z'; io.KeyMap[ImGuiKey_Z] = 'Z';
io.SetClipboardTextFn = [](void*, const char* str) -> void // Load cursors. Some of them are undocumented.
{ g_MouseCursorHidden = false;
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; g_MouseCursors[ImGuiMouseCursor_Arrow] = [NSCursor arrowCursor];
[pasteboard declareTypes:[NSArray arrayWithObject:NSPasteboardTypeString] owner:nil]; g_MouseCursors[ImGuiMouseCursor_TextInput] = [NSCursor IBeamCursor];
[pasteboard setString:[NSString stringWithUTF8String:str] forType:NSPasteboardTypeString]; g_MouseCursors[ImGuiMouseCursor_ResizeAll] = [NSCursor closedHandCursor];
}; g_MouseCursors[ImGuiMouseCursor_Hand] = [NSCursor pointingHandCursor];
g_MouseCursors[ImGuiMouseCursor_ResizeNS] = [NSCursor respondsToSelector:@selector(_windowResizeNorthSouthCursor)] ? [NSCursor _windowResizeNorthSouthCursor] : [NSCursor resizeUpDownCursor];
g_MouseCursors[ImGuiMouseCursor_ResizeEW] = [NSCursor respondsToSelector:@selector(_windowResizeEastWestCursor)] ? [NSCursor _windowResizeEastWestCursor] : [NSCursor resizeLeftRightCursor];
g_MouseCursors[ImGuiMouseCursor_ResizeNESW] = [NSCursor respondsToSelector:@selector(_windowResizeNorthEastSouthWestCursor)] ? [NSCursor _windowResizeNorthEastSouthWestCursor] : [NSCursor closedHandCursor];
g_MouseCursors[ImGuiMouseCursor_ResizeNWSE] = [NSCursor respondsToSelector:@selector(_windowResizeNorthWestSouthEastCursor)] ? [NSCursor _windowResizeNorthWestSouthEastCursor] : [NSCursor closedHandCursor];
io.GetClipboardTextFn = [](void*) -> const char* // We don't set the io.SetClipboardTextFn/io.GetClipboardTextFn handlers,
{ // because imgui.cpp has a default for them that works with OSX.
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
NSString* available = [pasteboard availableTypeFromArray: [NSArray arrayWithObject:NSPasteboardTypeString]];
if (![available isEqualToString:NSPasteboardTypeString])
return NULL;
NSString* string = [pasteboard stringForType:NSPasteboardTypeString];
if (string == nil)
return NULL;
const char* string_c = (const char*)[string UTF8String];
size_t string_len = strlen(string_c);
static ImVector<char> s_clipboard;
s_clipboard.resize((int)string_len + 1);
strcpy(s_clipboard.Data, string_c);
return s_clipboard.Data;
};
return true; return true;
} }
@ -87,6 +90,34 @@ void ImGui_ImplOSX_Shutdown()
{ {
} }
static void ImGui_ImplOSX_UpdateMouseCursor()
{
ImGuiIO& io = ImGui::GetIO();
if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
return;
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None)
{
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
if (!g_MouseCursorHidden)
{
g_MouseCursorHidden = true;
[NSCursor hide];
}
}
else
{
// Show OS mouse cursor
[g_MouseCursors[g_MouseCursors[imgui_cursor] ? imgui_cursor : ImGuiMouseCursor_Arrow] set];
if (g_MouseCursorHidden)
{
g_MouseCursorHidden = false;
[NSCursor unhide];
}
}
}
void ImGui_ImplOSX_NewFrame(NSView* view) void ImGui_ImplOSX_NewFrame(NSView* view)
{ {
// Setup display size // Setup display size
@ -101,6 +132,8 @@ void ImGui_ImplOSX_NewFrame(NSView* view)
CFAbsoluteTime current_time = CFAbsoluteTimeGetCurrent(); CFAbsoluteTime current_time = CFAbsoluteTimeGetCurrent();
io.DeltaTime = current_time - g_Time; io.DeltaTime = current_time - g_Time;
g_Time = current_time; g_Time = current_time;
ImGui_ImplOSX_UpdateMouseCursor();
} }
static int mapCharacterToKey(int c) static int mapCharacterToKey(int c)
@ -189,8 +222,8 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
for (int i = 0; i < len; i++) for (int i = 0; i < len; i++)
{ {
int c = [str characterAtIndex:i]; int c = [str characterAtIndex:i];
if (c < 0xF700 && !io.KeyCtrl) if (!io.KeyCtrl && !(c >= 0xF700 && c <= 0xFFFF))
io.AddInputCharacter((unsigned short)c); io.AddInputCharacter((unsigned int)c);
// We must reset in case we're pressing a sequence of special keys while keeping the command pressed // We must reset in case we're pressing a sequence of special keys while keeping the command pressed
int key = mapCharacterToKey(c); int key = mapCharacterToKey(c);

View File

@ -7,9 +7,9 @@
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// [X] Platform: Clipboard support. // [X] Platform: Clipboard support.
// [X] Platform: Keyboard arrays indexed using SDL_SCANCODE_* codes, e.g. ImGui::IsKeyPressed(SDL_SCANCODE_SPACE). // [X] Platform: Keyboard arrays indexed using SDL_SCANCODE_* codes, e.g. ImGui::IsKeyPressed(SDL_SCANCODE_SPACE).
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
// Missing features: // Missing features:
// [ ] Platform: SDL2 handling of IME under Windows appears to be broken and it explicitly disable the regular Windows IME. You can restore Windows IME by compiling SDL with SDL_DISABLE_WINDOWS_IME. // [ ] Platform: SDL2 handling of IME under Windows appears to be broken and it explicitly disable the regular Windows IME. You can restore Windows IME by compiling SDL with SDL_DISABLE_WINDOWS_IME.
// [ ] Platform: Gamepad support (need to use SDL_GameController API to fill the io.NavInputs[] value when ImGuiConfigFlags_NavEnableGamepad is set).
// 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 are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
@ -17,6 +17,8 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2019-04-23: Inputs: Added support for SDL_GameController (if ImGuiConfigFlags_NavEnableGamepad is set by user application).
// 2019-03-12: Misc: Preserve DisplayFramebufferScale when main window is minimized.
// 2018-12-21: Inputs: Workaround for Android/iOS which don't seem to handle focus related calls. // 2018-12-21: Inputs: Workaround for Android/iOS which don't seem to handle focus related calls.
// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window. // 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window.
// 2018-11-14: Changed the signature of ImGui_ImplSDL2_ProcessEvent() to take a 'const SDL_Event*'. // 2018-11-14: Changed the signature of ImGui_ImplSDL2_ProcessEvent() to take a 'const SDL_Event*'.
@ -41,7 +43,6 @@
#include "imgui_impl_sdl.h" #include "imgui_impl_sdl.h"
// SDL // SDL
// (the multi-viewports feature requires SDL features supported from SDL 2.0.5+)
#include <SDL.h> #include <SDL.h>
#include <SDL_syswm.h> #include <SDL_syswm.h>
#if defined(__APPLE__) #if defined(__APPLE__)
@ -50,9 +51,6 @@
#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE SDL_VERSION_ATLEAST(2,0,4) #define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE SDL_VERSION_ATLEAST(2,0,4)
#define SDL_HAS_VULKAN SDL_VERSION_ATLEAST(2,0,6) #define SDL_HAS_VULKAN SDL_VERSION_ATLEAST(2,0,6)
#if !SDL_HAS_VULKAN
static const Uint32 SDL_WINDOW_VULKAN = 0x10000000;
#endif
// Data // Data
static SDL_Window* g_Window = NULL; static SDL_Window* g_Window = NULL;
@ -268,6 +266,47 @@ static void ImGui_ImplSDL2_UpdateMouseCursor()
} }
} }
static void ImGui_ImplSDL2_UpdateGamepads()
{
ImGuiIO& io = ImGui::GetIO();
memset(io.NavInputs, 0, sizeof(io.NavInputs));
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
return;
// Get gamepad
SDL_GameController* game_controller = SDL_GameControllerOpen(0);
if (!game_controller)
{
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
return;
}
// Update gamepad inputs
#define MAP_BUTTON(NAV_NO, BUTTON_NO) { io.NavInputs[NAV_NO] = (SDL_GameControllerGetButton(game_controller, BUTTON_NO) != 0) ? 1.0f : 0.0f; }
#define MAP_ANALOG(NAV_NO, AXIS_NO, V0, V1) { float vn = (float)(SDL_GameControllerGetAxis(game_controller, AXIS_NO) - V0) / (float)(V1 - V0); if (vn > 1.0f) vn = 1.0f; if (vn > 0.0f && io.NavInputs[NAV_NO] < vn) io.NavInputs[NAV_NO] = vn; }
const int thumb_dead_zone = 8000; // SDL_gamecontroller.h suggests using this value.
MAP_BUTTON(ImGuiNavInput_Activate, SDL_CONTROLLER_BUTTON_A); // Cross / A
MAP_BUTTON(ImGuiNavInput_Cancel, SDL_CONTROLLER_BUTTON_B); // Circle / B
MAP_BUTTON(ImGuiNavInput_Menu, SDL_CONTROLLER_BUTTON_X); // Square / X
MAP_BUTTON(ImGuiNavInput_Input, SDL_CONTROLLER_BUTTON_Y); // Triangle / Y
MAP_BUTTON(ImGuiNavInput_DpadLeft, SDL_CONTROLLER_BUTTON_DPAD_LEFT); // D-Pad Left
MAP_BUTTON(ImGuiNavInput_DpadRight, SDL_CONTROLLER_BUTTON_DPAD_RIGHT); // D-Pad Right
MAP_BUTTON(ImGuiNavInput_DpadUp, SDL_CONTROLLER_BUTTON_DPAD_UP); // D-Pad Up
MAP_BUTTON(ImGuiNavInput_DpadDown, SDL_CONTROLLER_BUTTON_DPAD_DOWN); // D-Pad Down
MAP_BUTTON(ImGuiNavInput_FocusPrev, SDL_CONTROLLER_BUTTON_LEFTSHOULDER); // L1 / LB
MAP_BUTTON(ImGuiNavInput_FocusNext, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); // R1 / RB
MAP_BUTTON(ImGuiNavInput_TweakSlow, SDL_CONTROLLER_BUTTON_LEFTSHOULDER); // L1 / LB
MAP_BUTTON(ImGuiNavInput_TweakFast, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); // R1 / RB
MAP_ANALOG(ImGuiNavInput_LStickLeft, SDL_CONTROLLER_AXIS_LEFTX, -thumb_dead_zone, -32768);
MAP_ANALOG(ImGuiNavInput_LStickRight, SDL_CONTROLLER_AXIS_LEFTX, +thumb_dead_zone, +32767);
MAP_ANALOG(ImGuiNavInput_LStickUp, SDL_CONTROLLER_AXIS_LEFTY, -thumb_dead_zone, -32767);
MAP_ANALOG(ImGuiNavInput_LStickDown, SDL_CONTROLLER_AXIS_LEFTY, +thumb_dead_zone, +32767);
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
#undef MAP_BUTTON
#undef MAP_ANALOG
}
void ImGui_ImplSDL2_NewFrame(SDL_Window* window) void ImGui_ImplSDL2_NewFrame(SDL_Window* window)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
@ -279,7 +318,8 @@ void ImGui_ImplSDL2_NewFrame(SDL_Window* window)
SDL_GetWindowSize(window, &w, &h); SDL_GetWindowSize(window, &w, &h);
SDL_GL_GetDrawableSize(window, &display_w, &display_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); if (w > 0 && h > 0)
io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h);
// Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution) // Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution)
static Uint64 frequency = SDL_GetPerformanceFrequency(); static Uint64 frequency = SDL_GetPerformanceFrequency();
@ -289,4 +329,7 @@ void ImGui_ImplSDL2_NewFrame(SDL_Window* window)
ImGui_ImplSDL2_UpdateMousePosAndButtons(); ImGui_ImplSDL2_UpdateMousePosAndButtons();
ImGui_ImplSDL2_UpdateMouseCursor(); ImGui_ImplSDL2_UpdateMouseCursor();
// Update game controllers (if enabled and available)
ImGui_ImplSDL2_UpdateGamepads();
} }

View File

@ -6,9 +6,9 @@
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// [X] Platform: Clipboard support. // [X] Platform: Clipboard support.
// [X] Platform: Keyboard arrays indexed using SDL_SCANCODE_* codes, e.g. ImGui::IsKeyPressed(SDL_SCANCODE_SPACE). // [X] Platform: Keyboard arrays indexed using SDL_SCANCODE_* codes, e.g. ImGui::IsKeyPressed(SDL_SCANCODE_SPACE).
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
// Missing features: // Missing features:
// [ ] Platform: SDL2 handling of IME under Windows appears to be broken and it explicitly disable the regular Windows IME. You can restore Windows IME by compiling SDL with SDL_DISABLE_WINDOWS_IME. // [ ] Platform: SDL2 handling of IME under Windows appears to be broken and it explicitly disable the regular Windows IME. You can restore Windows IME by compiling SDL with SDL_DISABLE_WINDOWS_IME.
// [ ] Platform: Gamepad support (need to use SDL_GameController API to fill the io.NavInputs[] value when ImGuiConfigFlags_NavEnableGamepad is set).
// 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 are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.

View File

@ -1,6 +1,8 @@
// dear imgui: Renderer for Vulkan // dear imgui: Renderer for Vulkan
// This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..) // This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..)
// Implemented features:
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bits indices.
// Missing features: // Missing features:
// [ ] Renderer: User texture binding. Changes of ImTextureID aren't supported by this binding! See https://github.com/ocornut/imgui/pull/914 // [ ] Renderer: User texture binding. Changes of ImTextureID aren't supported by this binding! See https://github.com/ocornut/imgui/pull/914
@ -11,8 +13,22 @@
// The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification. // The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification.
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/ // IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
// Important note to the reader who wish to integrate imgui_impl_vulkan.cpp/.h in their own engine/app.
// - Common ImGui_ImplVulkan_XXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h.
// You will use those if you want to use this rendering back-end in your engine/app.
// - Helper ImGui_ImplVulkanH_XXX functions and structures are only used by this example (main.cpp) and by
// the back-end itself (imgui_impl_vulkan.cpp), but should PROBABLY NOT be used by your own engine/app code.
// Read comments in imgui_impl_vulkan.h.
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2019-05-29: Vulkan: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
// 2019-04-30: Vulkan: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
// 2019-04-04: *BREAKING CHANGE*: Vulkan: Added ImageCount/MinImageCount fields in ImGui_ImplVulkan_InitInfo, required for initialization (was previously a hard #define IMGUI_VK_QUEUED_FRAMES 2). Added ImGui_ImplVulkan_SetMinImageCount().
// 2019-04-04: Vulkan: Added VkInstance argument to ImGui_ImplVulkanH_CreateWindow() optional helper.
// 2019-04-04: Vulkan: Avoid passing negative coordinates to vkCmdSetScissor, which debug validation layers do not like.
// 2019-04-01: Vulkan: Support for 32-bit index buffer (#define ImDrawIdx unsigned int).
// 2019-02-16: Vulkan: Viewport and clipping rectangles correctly using draw_data->FramebufferScale to allow retina display.
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. // 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
// 2018-08-25: Vulkan: Fixed mishandled VkSurfaceCapabilitiesKHR::maxImageCount=0 case. // 2018-08-25: Vulkan: Fixed mishandled VkSurfaceCapabilitiesKHR::maxImageCount=0 case.
// 2018-06-22: Inverted the parameters to ImGui_ImplVulkan_RenderDrawData() to be consistent with other bindings. // 2018-06-22: Inverted the parameters to ImGui_ImplVulkan_RenderDrawData() to be consistent with other bindings.
@ -31,28 +47,9 @@
#include "imgui_impl_vulkan.h" #include "imgui_impl_vulkan.h"
#include <stdio.h> #include <stdio.h>
// Vulkan data // Reusable buffers used for rendering 1 current in-flight frame, for ImGui_ImplVulkan_RenderDrawData()
static const VkAllocationCallbacks* g_Allocator = NULL; // [Please zero-clear before use!]
static VkPhysicalDevice g_PhysicalDevice = VK_NULL_HANDLE; struct ImGui_ImplVulkanH_FrameRenderBuffers
static VkInstance g_Instance = VK_NULL_HANDLE;
static VkDevice g_Device = VK_NULL_HANDLE;
static uint32_t g_QueueFamily = (uint32_t)-1;
static VkQueue g_Queue = VK_NULL_HANDLE;
static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE;
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
static VkRenderPass g_RenderPass = VK_NULL_HANDLE;
static void (*g_CheckVkResultFn)(VkResult err) = NULL;
static VkDeviceSize g_BufferMemoryAlignment = 256;
static VkPipelineCreateFlags g_PipelineCreateFlags = 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;
// Frame data
struct FrameDataForRender
{ {
VkDeviceMemory VertexBufferMemory; VkDeviceMemory VertexBufferMemory;
VkDeviceMemory IndexBufferMemory; VkDeviceMemory IndexBufferMemory;
@ -61,8 +58,25 @@ struct FrameDataForRender
VkBuffer VertexBuffer; VkBuffer VertexBuffer;
VkBuffer IndexBuffer; VkBuffer IndexBuffer;
}; };
static int g_FrameIndex = 0;
static FrameDataForRender g_FramesDataBuffers[IMGUI_VK_QUEUED_FRAMES] = {}; // Each viewport will hold 1 ImGui_ImplVulkanH_WindowRenderBuffers
// [Please zero-clear before use!]
struct ImGui_ImplVulkanH_WindowRenderBuffers
{
uint32_t Index;
uint32_t Count;
ImGui_ImplVulkanH_FrameRenderBuffers* FrameRenderBuffers;
};
// Vulkan data
static ImGui_ImplVulkan_InitInfo g_VulkanInitInfo = {};
static VkRenderPass g_RenderPass = VK_NULL_HANDLE;
static VkDeviceSize g_BufferMemoryAlignment = 256;
static VkPipelineCreateFlags g_PipelineCreateFlags = 0x00;
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;
// Font data // Font data
static VkSampler g_FontSampler = VK_NULL_HANDLE; static VkSampler g_FontSampler = VK_NULL_HANDLE;
@ -72,8 +86,42 @@ static VkImageView g_FontView = VK_NULL_HANDLE;
static VkDeviceMemory g_UploadBufferMemory = VK_NULL_HANDLE; static VkDeviceMemory g_UploadBufferMemory = VK_NULL_HANDLE;
static VkBuffer g_UploadBuffer = VK_NULL_HANDLE; static VkBuffer g_UploadBuffer = VK_NULL_HANDLE;
// Render buffers
static ImGui_ImplVulkanH_WindowRenderBuffers g_MainWindowRenderBuffers;
// Forward Declarations
bool ImGui_ImplVulkan_CreateDeviceObjects();
void ImGui_ImplVulkan_DestroyDeviceObjects();
void ImGui_ImplVulkanH_DestroyFrame(VkDevice device, ImGui_ImplVulkanH_Frame* fd, const VkAllocationCallbacks* allocator);
void ImGui_ImplVulkanH_DestroyFrameSemaphores(VkDevice device, ImGui_ImplVulkanH_FrameSemaphores* fsd, const VkAllocationCallbacks* allocator);
void ImGui_ImplVulkanH_DestroyFrameRenderBuffers(VkDevice device, ImGui_ImplVulkanH_FrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator);
void ImGui_ImplVulkanH_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulkanH_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator);
void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count);
void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator);
//-----------------------------------------------------------------------------
// SHADERS
//-----------------------------------------------------------------------------
// glsl_shader.vert, compiled with: // glsl_shader.vert, compiled with:
// # glslangValidator -V -x -o glsl_shader.vert.u32 glsl_shader.vert // # glslangValidator -V -x -o glsl_shader.vert.u32 glsl_shader.vert
/*
#version 450 core
layout(location = 0) in vec2 aPos;
layout(location = 1) in vec2 aUV;
layout(location = 2) in vec4 aColor;
layout(push_constant) uniform uPushConstant { vec2 uScale; vec2 uTranslate; } pc;
out gl_PerVertex { vec4 gl_Position; };
layout(location = 0) out struct { vec4 Color; vec2 UV; } Out;
void main()
{
Out.Color = aColor;
Out.UV = aUV;
gl_Position = vec4(aPos * pc.uScale + pc.uTranslate, 0, 1);
}
*/
static uint32_t __glsl_shader_vert_spv[] = static uint32_t __glsl_shader_vert_spv[] =
{ {
0x07230203,0x00010000,0x00080001,0x0000002e,0x00000000,0x00020011,0x00000001,0x0006000b, 0x07230203,0x00010000,0x00080001,0x0000002e,0x00000000,0x00020011,0x00000001,0x0006000b,
@ -121,6 +169,16 @@ static uint32_t __glsl_shader_vert_spv[] =
// glsl_shader.frag, compiled with: // glsl_shader.frag, compiled with:
// # glslangValidator -V -x -o glsl_shader.frag.u32 glsl_shader.frag // # glslangValidator -V -x -o glsl_shader.frag.u32 glsl_shader.frag
/*
#version 450 core
layout(location = 0) out vec4 fColor;
layout(set=0, binding=0) uniform sampler2D sTexture;
layout(location = 0) in struct { vec4 Color; vec2 UV; } In;
void main()
{
fColor = In.Color * texture(sTexture, In.UV.st);
}
*/
static uint32_t __glsl_shader_frag_spv[] = static uint32_t __glsl_shader_frag_spv[] =
{ {
0x07230203,0x00010000,0x00080001,0x0000001e,0x00000000,0x00020011,0x00000001,0x0006000b, 0x07230203,0x00010000,0x00080001,0x0000001e,0x00000000,0x00020011,0x00000001,0x0006000b,
@ -150,10 +208,15 @@ static uint32_t __glsl_shader_frag_spv[] =
0x00010038 0x00010038
}; };
//-----------------------------------------------------------------------------
// FUNCTIONS
//-----------------------------------------------------------------------------
static uint32_t ImGui_ImplVulkan_MemoryType(VkMemoryPropertyFlags properties, uint32_t type_bits) static uint32_t ImGui_ImplVulkan_MemoryType(VkMemoryPropertyFlags properties, uint32_t type_bits)
{ {
ImGui_ImplVulkan_InitInfo* v = &g_VulkanInitInfo;
VkPhysicalDeviceMemoryProperties prop; VkPhysicalDeviceMemoryProperties prop;
vkGetPhysicalDeviceMemoryProperties(g_PhysicalDevice, &prop); vkGetPhysicalDeviceMemoryProperties(v->PhysicalDevice, &prop);
for (uint32_t i = 0; i < prop.memoryTypeCount; i++) for (uint32_t i = 0; i < prop.memoryTypeCount; i++)
if ((prop.memoryTypes[i].propertyFlags & properties) == properties && type_bits & (1<<i)) if ((prop.memoryTypes[i].propertyFlags & properties) == properties && type_bits & (1<<i))
return i; return i;
@ -162,17 +225,19 @@ static uint32_t ImGui_ImplVulkan_MemoryType(VkMemoryPropertyFlags properties, ui
static void check_vk_result(VkResult err) static void check_vk_result(VkResult err)
{ {
if (g_CheckVkResultFn) ImGui_ImplVulkan_InitInfo* v = &g_VulkanInitInfo;
g_CheckVkResultFn(err); if (v->CheckVkResultFn)
v->CheckVkResultFn(err);
} }
static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory, VkDeviceSize& p_buffer_size, size_t new_size, VkBufferUsageFlagBits usage) static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory, VkDeviceSize& p_buffer_size, size_t new_size, VkBufferUsageFlagBits usage)
{ {
ImGui_ImplVulkan_InitInfo* v = &g_VulkanInitInfo;
VkResult err; VkResult err;
if (buffer != VK_NULL_HANDLE) if (buffer != VK_NULL_HANDLE)
vkDestroyBuffer(g_Device, buffer, g_Allocator); vkDestroyBuffer(v->Device, buffer, v->Allocator);
if (buffer_memory) if (buffer_memory != VK_NULL_HANDLE)
vkFreeMemory(g_Device, buffer_memory, g_Allocator); vkFreeMemory(v->Device, buffer_memory, v->Allocator);
VkDeviceSize vertex_buffer_size_aligned = ((new_size - 1) / g_BufferMemoryAlignment + 1) * g_BufferMemoryAlignment; VkDeviceSize vertex_buffer_size_aligned = ((new_size - 1) / g_BufferMemoryAlignment + 1) * g_BufferMemoryAlignment;
VkBufferCreateInfo buffer_info = {}; VkBufferCreateInfo buffer_info = {};
@ -180,50 +245,109 @@ static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory
buffer_info.size = vertex_buffer_size_aligned; buffer_info.size = vertex_buffer_size_aligned;
buffer_info.usage = usage; buffer_info.usage = usage;
buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
err = vkCreateBuffer(g_Device, &buffer_info, g_Allocator, &buffer); err = vkCreateBuffer(v->Device, &buffer_info, v->Allocator, &buffer);
check_vk_result(err); check_vk_result(err);
VkMemoryRequirements req; VkMemoryRequirements req;
vkGetBufferMemoryRequirements(g_Device, buffer, &req); vkGetBufferMemoryRequirements(v->Device, buffer, &req);
g_BufferMemoryAlignment = (g_BufferMemoryAlignment > req.alignment) ? g_BufferMemoryAlignment : req.alignment; g_BufferMemoryAlignment = (g_BufferMemoryAlignment > req.alignment) ? g_BufferMemoryAlignment : req.alignment;
VkMemoryAllocateInfo alloc_info = {}; VkMemoryAllocateInfo alloc_info = {};
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
alloc_info.allocationSize = req.size; alloc_info.allocationSize = req.size;
alloc_info.memoryTypeIndex = ImGui_ImplVulkan_MemoryType(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, req.memoryTypeBits); alloc_info.memoryTypeIndex = ImGui_ImplVulkan_MemoryType(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, req.memoryTypeBits);
err = vkAllocateMemory(g_Device, &alloc_info, g_Allocator, &buffer_memory); err = vkAllocateMemory(v->Device, &alloc_info, v->Allocator, &buffer_memory);
check_vk_result(err); check_vk_result(err);
err = vkBindBufferMemory(g_Device, buffer, buffer_memory, 0); err = vkBindBufferMemory(v->Device, buffer, buffer_memory, 0);
check_vk_result(err); check_vk_result(err);
p_buffer_size = new_size; p_buffer_size = new_size;
} }
static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkCommandBuffer command_buffer, ImGui_ImplVulkanH_FrameRenderBuffers* rb, int fb_width, int fb_height)
{
// Bind pipeline and descriptor sets:
{
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_Pipeline);
VkDescriptorSet desc_set[1] = { g_DescriptorSet };
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_PipelineLayout, 0, 1, desc_set, 0, NULL);
}
// Bind Vertex And Index Buffer:
{
VkBuffer vertex_buffers[1] = { rb->VertexBuffer };
VkDeviceSize vertex_offset[1] = { 0 };
vkCmdBindVertexBuffers(command_buffer, 0, 1, vertex_buffers, vertex_offset);
vkCmdBindIndexBuffer(command_buffer, rb->IndexBuffer, 0, sizeof(ImDrawIdx) == 2 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32);
}
// Setup viewport:
{
VkViewport viewport;
viewport.x = 0;
viewport.y = 0;
viewport.width = (float)fb_width;
viewport.height = (float)fb_height;
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
vkCmdSetViewport(command_buffer, 0, 1, &viewport);
}
// Setup scale and translation:
// Our visible imgui space lies from draw_data->DisplayPps (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
{
float scale[2];
scale[0] = 2.0f / draw_data->DisplaySize.x;
scale[1] = 2.0f / draw_data->DisplaySize.y;
float translate[2];
translate[0] = -1.0f - draw_data->DisplayPos.x * scale[0];
translate[1] = -1.0f - draw_data->DisplayPos.y * scale[1];
vkCmdPushConstants(command_buffer, g_PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, sizeof(float) * 0, sizeof(float) * 2, scale);
vkCmdPushConstants(command_buffer, g_PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, sizeof(float) * 2, sizeof(float) * 2, translate);
}
}
// Render function // Render function
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer) void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer)
{ {
VkResult err; // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
if (draw_data->TotalVtxCount == 0) int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
if (fb_width <= 0 || fb_height <= 0 || draw_data->TotalVtxCount == 0)
return; return;
FrameDataForRender* fd = &g_FramesDataBuffers[g_FrameIndex]; ImGui_ImplVulkan_InitInfo* v = &g_VulkanInitInfo;
g_FrameIndex = (g_FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES;
// Create the Vertex and Index buffers: // Allocate array to store enough vertex/index buffers
ImGui_ImplVulkanH_WindowRenderBuffers* wrb = &g_MainWindowRenderBuffers;
if (wrb->FrameRenderBuffers == NULL)
{
wrb->Index = 0;
wrb->Count = v->ImageCount;
wrb->FrameRenderBuffers = (ImGui_ImplVulkanH_FrameRenderBuffers*)IM_ALLOC(sizeof(ImGui_ImplVulkanH_FrameRenderBuffers) * wrb->Count);
memset(wrb->FrameRenderBuffers, 0, sizeof(ImGui_ImplVulkanH_FrameRenderBuffers) * wrb->Count);
}
IM_ASSERT(wrb->Count == v->ImageCount);
wrb->Index = (wrb->Index + 1) % wrb->Count;
ImGui_ImplVulkanH_FrameRenderBuffers* rb = &wrb->FrameRenderBuffers[wrb->Index];
VkResult err;
// Create or resize the vertex/index buffers
size_t vertex_size = draw_data->TotalVtxCount * sizeof(ImDrawVert); size_t vertex_size = draw_data->TotalVtxCount * sizeof(ImDrawVert);
size_t index_size = draw_data->TotalIdxCount * sizeof(ImDrawIdx); size_t index_size = draw_data->TotalIdxCount * sizeof(ImDrawIdx);
if (!fd->VertexBuffer || fd->VertexBufferSize < vertex_size) if (rb->VertexBuffer == VK_NULL_HANDLE || rb->VertexBufferSize < vertex_size)
CreateOrResizeBuffer(fd->VertexBuffer, fd->VertexBufferMemory, fd->VertexBufferSize, vertex_size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); CreateOrResizeBuffer(rb->VertexBuffer, rb->VertexBufferMemory, rb->VertexBufferSize, vertex_size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
if (!fd->IndexBuffer || fd->IndexBufferSize < index_size) if (rb->IndexBuffer == VK_NULL_HANDLE || rb->IndexBufferSize < index_size)
CreateOrResizeBuffer(fd->IndexBuffer, fd->IndexBufferMemory, fd->IndexBufferSize, index_size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); CreateOrResizeBuffer(rb->IndexBuffer, rb->IndexBufferMemory, rb->IndexBufferSize, index_size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
// Upload Vertex and index Data: // Upload vertex/index data into a single contiguous GPU buffer
{ {
ImDrawVert* vtx_dst = NULL; ImDrawVert* vtx_dst = NULL;
ImDrawIdx* idx_dst = NULL; ImDrawIdx* idx_dst = NULL;
err = vkMapMemory(g_Device, fd->VertexBufferMemory, 0, vertex_size, 0, (void**)(&vtx_dst)); err = vkMapMemory(v->Device, rb->VertexBufferMemory, 0, vertex_size, 0, (void**)(&vtx_dst));
check_vk_result(err); check_vk_result(err);
err = vkMapMemory(g_Device, fd->IndexBufferMemory, 0, index_size, 0, (void**)(&idx_dst)); err = vkMapMemory(v->Device, rb->IndexBufferMemory, 0, index_size, 0, (void**)(&idx_dst));
check_vk_result(err); check_vk_result(err);
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {
@ -235,93 +359,81 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
} }
VkMappedMemoryRange range[2] = {}; VkMappedMemoryRange range[2] = {};
range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
range[0].memory = fd->VertexBufferMemory; range[0].memory = rb->VertexBufferMemory;
range[0].size = VK_WHOLE_SIZE; range[0].size = VK_WHOLE_SIZE;
range[1].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; range[1].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
range[1].memory = fd->IndexBufferMemory; range[1].memory = rb->IndexBufferMemory;
range[1].size = VK_WHOLE_SIZE; range[1].size = VK_WHOLE_SIZE;
err = vkFlushMappedMemoryRanges(g_Device, 2, range); err = vkFlushMappedMemoryRanges(v->Device, 2, range);
check_vk_result(err); check_vk_result(err);
vkUnmapMemory(g_Device, fd->VertexBufferMemory); vkUnmapMemory(v->Device, rb->VertexBufferMemory);
vkUnmapMemory(g_Device, fd->IndexBufferMemory); vkUnmapMemory(v->Device, rb->IndexBufferMemory);
} }
// Bind pipeline and descriptor sets: // Setup desired Vulkan state
{ ImGui_ImplVulkan_SetupRenderState(draw_data, command_buffer, rb, fb_width, fb_height);
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_Pipeline);
VkDescriptorSet desc_set[1] = { g_DescriptorSet };
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_PipelineLayout, 0, 1, desc_set, 0, NULL);
}
// Bind Vertex And Index Buffer: // Will project scissor/clipping rectangles into framebuffer space
{ ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
VkBuffer vertex_buffers[1] = { fd->VertexBuffer }; ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
VkDeviceSize vertex_offset[1] = { 0 };
vkCmdBindVertexBuffers(command_buffer, 0, 1, vertex_buffers, vertex_offset);
vkCmdBindIndexBuffer(command_buffer, fd->IndexBuffer, 0, VK_INDEX_TYPE_UINT16);
}
// Setup viewport: // Render command lists
{ // (Because we merged all buffers into a single one, we maintain our own offset into them)
VkViewport viewport; int global_vtx_offset = 0;
viewport.x = 0; int global_idx_offset = 0;
viewport.y = 0;
viewport.width = draw_data->DisplaySize.x;
viewport.height = draw_data->DisplaySize.y;
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
vkCmdSetViewport(command_buffer, 0, 1, &viewport);
}
// Setup scale and translation:
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayMin is typically (0,0) for single viewport apps.
{
float scale[2];
scale[0] = 2.0f / draw_data->DisplaySize.x;
scale[1] = 2.0f / draw_data->DisplaySize.y;
float translate[2];
translate[0] = -1.0f - draw_data->DisplayPos.x * scale[0];
translate[1] = -1.0f - draw_data->DisplayPos.y * scale[1];
vkCmdPushConstants(command_buffer, g_PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, sizeof(float) * 0, sizeof(float) * 2, scale);
vkCmdPushConstants(command_buffer, 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;
ImVec2 display_pos = draw_data->DisplayPos;
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];
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{ {
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback) if (pcmd->UserCallback != NULL)
{ {
// User callback, registered via ImDrawList::AddCallback()
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplVulkan_SetupRenderState(draw_data, command_buffer, rb, fb_width, fb_height);
else
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(cmd_list, pcmd);
} }
else else
{ {
// Project scissor/clipping rectangles into framebuffer space
ImVec4 clip_rect;
clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x;
clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y;
clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x;
clip_rect.w = (pcmd->ClipRect.w - clip_off.y) * clip_scale.y;
if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f)
{
// Negative offsets are illegal for vkCmdSetScissor
if (clip_rect.x < 0.0f)
clip_rect.x = 0.0f;
if (clip_rect.y < 0.0f)
clip_rect.y = 0.0f;
// Apply scissor/clipping rectangle // Apply scissor/clipping rectangle
// FIXME: We could clamp width/height based on clamped min/max values.
VkRect2D scissor; VkRect2D scissor;
scissor.offset.x = (int32_t)(pcmd->ClipRect.x - display_pos.x) > 0 ? (int32_t)(pcmd->ClipRect.x - display_pos.x) : 0; scissor.offset.x = (int32_t)(clip_rect.x);
scissor.offset.y = (int32_t)(pcmd->ClipRect.y - display_pos.y) > 0 ? (int32_t)(pcmd->ClipRect.y - display_pos.y) : 0; scissor.offset.y = (int32_t)(clip_rect.y);
scissor.extent.width = (uint32_t)(pcmd->ClipRect.z - pcmd->ClipRect.x); scissor.extent.width = (uint32_t)(clip_rect.z - clip_rect.x);
scissor.extent.height = (uint32_t)(pcmd->ClipRect.w - pcmd->ClipRect.y + 1); // FIXME: Why +1 here? scissor.extent.height = (uint32_t)(clip_rect.w - clip_rect.y);
vkCmdSetScissor(command_buffer, 0, 1, &scissor); vkCmdSetScissor(command_buffer, 0, 1, &scissor);
// Draw // Draw
vkCmdDrawIndexed(command_buffer, pcmd->ElemCount, 1, idx_offset, vtx_offset, 0); vkCmdDrawIndexed(command_buffer, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
} }
idx_offset += pcmd->ElemCount;
} }
vtx_offset += cmd_list->VtxBuffer.Size; }
global_idx_offset += cmd_list->IdxBuffer.Size;
global_vtx_offset += cmd_list->VtxBuffer.Size;
} }
} }
bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer) bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer)
{ {
ImGui_ImplVulkan_InitInfo* v = &g_VulkanInitInfo;
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
unsigned char* pixels; unsigned char* pixels;
@ -347,17 +459,17 @@ bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer)
info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
err = vkCreateImage(g_Device, &info, g_Allocator, &g_FontImage); err = vkCreateImage(v->Device, &info, v->Allocator, &g_FontImage);
check_vk_result(err); check_vk_result(err);
VkMemoryRequirements req; VkMemoryRequirements req;
vkGetImageMemoryRequirements(g_Device, g_FontImage, &req); vkGetImageMemoryRequirements(v->Device, g_FontImage, &req);
VkMemoryAllocateInfo alloc_info = {}; VkMemoryAllocateInfo alloc_info = {};
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
alloc_info.allocationSize = req.size; alloc_info.allocationSize = req.size;
alloc_info.memoryTypeIndex = ImGui_ImplVulkan_MemoryType(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, req.memoryTypeBits); alloc_info.memoryTypeIndex = ImGui_ImplVulkan_MemoryType(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, req.memoryTypeBits);
err = vkAllocateMemory(g_Device, &alloc_info, g_Allocator, &g_FontMemory); err = vkAllocateMemory(v->Device, &alloc_info, v->Allocator, &g_FontMemory);
check_vk_result(err); check_vk_result(err);
err = vkBindImageMemory(g_Device, g_FontImage, g_FontMemory, 0); err = vkBindImageMemory(v->Device, g_FontImage, g_FontMemory, 0);
check_vk_result(err); check_vk_result(err);
} }
@ -371,7 +483,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer)
info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
info.subresourceRange.levelCount = 1; info.subresourceRange.levelCount = 1;
info.subresourceRange.layerCount = 1; info.subresourceRange.layerCount = 1;
err = vkCreateImageView(g_Device, &info, g_Allocator, &g_FontView); err = vkCreateImageView(v->Device, &info, v->Allocator, &g_FontView);
check_vk_result(err); check_vk_result(err);
} }
@ -387,7 +499,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer)
write_desc[0].descriptorCount = 1; write_desc[0].descriptorCount = 1;
write_desc[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; write_desc[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
write_desc[0].pImageInfo = desc_image; write_desc[0].pImageInfo = desc_image;
vkUpdateDescriptorSets(g_Device, 1, write_desc, 0, NULL); vkUpdateDescriptorSets(v->Device, 1, write_desc, 0, NULL);
} }
// Create the Upload Buffer: // Create the Upload Buffer:
@ -397,34 +509,34 @@ bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer)
buffer_info.size = upload_size; buffer_info.size = upload_size;
buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
err = vkCreateBuffer(g_Device, &buffer_info, g_Allocator, &g_UploadBuffer); err = vkCreateBuffer(v->Device, &buffer_info, v->Allocator, &g_UploadBuffer);
check_vk_result(err); check_vk_result(err);
VkMemoryRequirements req; VkMemoryRequirements req;
vkGetBufferMemoryRequirements(g_Device, g_UploadBuffer, &req); vkGetBufferMemoryRequirements(v->Device, g_UploadBuffer, &req);
g_BufferMemoryAlignment = (g_BufferMemoryAlignment > req.alignment) ? g_BufferMemoryAlignment : req.alignment; g_BufferMemoryAlignment = (g_BufferMemoryAlignment > req.alignment) ? g_BufferMemoryAlignment : req.alignment;
VkMemoryAllocateInfo alloc_info = {}; VkMemoryAllocateInfo alloc_info = {};
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
alloc_info.allocationSize = req.size; alloc_info.allocationSize = req.size;
alloc_info.memoryTypeIndex = ImGui_ImplVulkan_MemoryType(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, req.memoryTypeBits); alloc_info.memoryTypeIndex = ImGui_ImplVulkan_MemoryType(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, req.memoryTypeBits);
err = vkAllocateMemory(g_Device, &alloc_info, g_Allocator, &g_UploadBufferMemory); err = vkAllocateMemory(v->Device, &alloc_info, v->Allocator, &g_UploadBufferMemory);
check_vk_result(err); check_vk_result(err);
err = vkBindBufferMemory(g_Device, g_UploadBuffer, g_UploadBufferMemory, 0); err = vkBindBufferMemory(v->Device, g_UploadBuffer, g_UploadBufferMemory, 0);
check_vk_result(err); check_vk_result(err);
} }
// Upload to Buffer: // Upload to Buffer:
{ {
char* map = NULL; char* map = NULL;
err = vkMapMemory(g_Device, g_UploadBufferMemory, 0, upload_size, 0, (void**)(&map)); err = vkMapMemory(v->Device, g_UploadBufferMemory, 0, upload_size, 0, (void**)(&map));
check_vk_result(err); check_vk_result(err);
memcpy(map, pixels, upload_size); memcpy(map, pixels, upload_size);
VkMappedMemoryRange range[1] = {}; VkMappedMemoryRange range[1] = {};
range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
range[0].memory = g_UploadBufferMemory; range[0].memory = g_UploadBufferMemory;
range[0].size = upload_size; range[0].size = upload_size;
err = vkFlushMappedMemoryRanges(g_Device, 1, range); err = vkFlushMappedMemoryRanges(v->Device, 1, range);
check_vk_result(err); check_vk_result(err);
vkUnmapMemory(g_Device, g_UploadBufferMemory); vkUnmapMemory(v->Device, g_UploadBufferMemory);
} }
// Copy to Image: // Copy to Image:
@ -473,6 +585,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer)
bool ImGui_ImplVulkan_CreateDeviceObjects() bool ImGui_ImplVulkan_CreateDeviceObjects()
{ {
ImGui_ImplVulkan_InitInfo* v = &g_VulkanInitInfo;
VkResult err; VkResult err;
VkShaderModule vert_module; VkShaderModule vert_module;
VkShaderModule frag_module; VkShaderModule frag_module;
@ -483,13 +596,13 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
vert_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; vert_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
vert_info.codeSize = sizeof(__glsl_shader_vert_spv); vert_info.codeSize = sizeof(__glsl_shader_vert_spv);
vert_info.pCode = (uint32_t*)__glsl_shader_vert_spv; vert_info.pCode = (uint32_t*)__glsl_shader_vert_spv;
err = vkCreateShaderModule(g_Device, &vert_info, g_Allocator, &vert_module); err = vkCreateShaderModule(v->Device, &vert_info, v->Allocator, &vert_module);
check_vk_result(err); check_vk_result(err);
VkShaderModuleCreateInfo frag_info = {}; VkShaderModuleCreateInfo frag_info = {};
frag_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; frag_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
frag_info.codeSize = sizeof(__glsl_shader_frag_spv); frag_info.codeSize = sizeof(__glsl_shader_frag_spv);
frag_info.pCode = (uint32_t*)__glsl_shader_frag_spv; frag_info.pCode = (uint32_t*)__glsl_shader_frag_spv;
err = vkCreateShaderModule(g_Device, &frag_info, g_Allocator, &frag_module); err = vkCreateShaderModule(v->Device, &frag_info, v->Allocator, &frag_module);
check_vk_result(err); check_vk_result(err);
} }
@ -506,7 +619,7 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
info.minLod = -1000; info.minLod = -1000;
info.maxLod = 1000; info.maxLod = 1000;
info.maxAnisotropy = 1.0f; info.maxAnisotropy = 1.0f;
err = vkCreateSampler(g_Device, &info, g_Allocator, &g_FontSampler); err = vkCreateSampler(v->Device, &info, v->Allocator, &g_FontSampler);
check_vk_result(err); check_vk_result(err);
} }
@ -522,7 +635,7 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
info.bindingCount = 1; info.bindingCount = 1;
info.pBindings = binding; info.pBindings = binding;
err = vkCreateDescriptorSetLayout(g_Device, &info, g_Allocator, &g_DescriptorSetLayout); err = vkCreateDescriptorSetLayout(v->Device, &info, v->Allocator, &g_DescriptorSetLayout);
check_vk_result(err); check_vk_result(err);
} }
@ -530,10 +643,10 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
{ {
VkDescriptorSetAllocateInfo alloc_info = {}; VkDescriptorSetAllocateInfo alloc_info = {};
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
alloc_info.descriptorPool = g_DescriptorPool; alloc_info.descriptorPool = v->DescriptorPool;
alloc_info.descriptorSetCount = 1; alloc_info.descriptorSetCount = 1;
alloc_info.pSetLayouts = &g_DescriptorSetLayout; alloc_info.pSetLayouts = &g_DescriptorSetLayout;
err = vkAllocateDescriptorSets(g_Device, &alloc_info, &g_DescriptorSet); err = vkAllocateDescriptorSets(v->Device, &alloc_info, &g_DescriptorSet);
check_vk_result(err); check_vk_result(err);
} }
@ -551,7 +664,7 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
layout_info.pSetLayouts = set_layout; layout_info.pSetLayouts = set_layout;
layout_info.pushConstantRangeCount = 1; layout_info.pushConstantRangeCount = 1;
layout_info.pPushConstantRanges = push_constants; layout_info.pPushConstantRanges = push_constants;
err = vkCreatePipelineLayout(g_Device, &layout_info, g_Allocator, &g_PipelineLayout); err = vkCreatePipelineLayout(v->Device, &layout_info, v->Allocator, &g_PipelineLayout);
check_vk_result(err); check_vk_result(err);
} }
@ -649,74 +762,63 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
info.pDynamicState = &dynamic_state; info.pDynamicState = &dynamic_state;
info.layout = g_PipelineLayout; info.layout = g_PipelineLayout;
info.renderPass = g_RenderPass; info.renderPass = g_RenderPass;
err = vkCreateGraphicsPipelines(g_Device, g_PipelineCache, 1, &info, g_Allocator, &g_Pipeline); err = vkCreateGraphicsPipelines(v->Device, v->PipelineCache, 1, &info, v->Allocator, &g_Pipeline);
check_vk_result(err); check_vk_result(err);
vkDestroyShaderModule(g_Device, vert_module, g_Allocator); vkDestroyShaderModule(v->Device, vert_module, v->Allocator);
vkDestroyShaderModule(g_Device, frag_module, g_Allocator); vkDestroyShaderModule(v->Device, frag_module, v->Allocator);
return true; return true;
} }
void ImGui_ImplVulkan_InvalidateFontUploadObjects() void ImGui_ImplVulkan_DestroyFontUploadObjects()
{ {
ImGui_ImplVulkan_InitInfo* v = &g_VulkanInitInfo;
if (g_UploadBuffer) if (g_UploadBuffer)
{ {
vkDestroyBuffer(g_Device, g_UploadBuffer, g_Allocator); vkDestroyBuffer(v->Device, g_UploadBuffer, v->Allocator);
g_UploadBuffer = VK_NULL_HANDLE; g_UploadBuffer = VK_NULL_HANDLE;
} }
if (g_UploadBufferMemory) if (g_UploadBufferMemory)
{ {
vkFreeMemory(g_Device, g_UploadBufferMemory, g_Allocator); vkFreeMemory(v->Device, g_UploadBufferMemory, v->Allocator);
g_UploadBufferMemory = VK_NULL_HANDLE; g_UploadBufferMemory = VK_NULL_HANDLE;
} }
} }
void ImGui_ImplVulkan_InvalidateDeviceObjects() void ImGui_ImplVulkan_DestroyDeviceObjects()
{ {
ImGui_ImplVulkan_InvalidateFontUploadObjects(); ImGui_ImplVulkan_InitInfo* v = &g_VulkanInitInfo;
ImGui_ImplVulkanH_DestroyWindowRenderBuffers(v->Device, &g_MainWindowRenderBuffers, v->Allocator);
ImGui_ImplVulkan_DestroyFontUploadObjects();
for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++) if (g_FontView) { vkDestroyImageView(v->Device, g_FontView, v->Allocator); g_FontView = VK_NULL_HANDLE; }
{ if (g_FontImage) { vkDestroyImage(v->Device, g_FontImage, v->Allocator); g_FontImage = VK_NULL_HANDLE; }
FrameDataForRender* fd = &g_FramesDataBuffers[i]; if (g_FontMemory) { vkFreeMemory(v->Device, g_FontMemory, v->Allocator); g_FontMemory = VK_NULL_HANDLE; }
if (fd->VertexBuffer) { vkDestroyBuffer (g_Device, fd->VertexBuffer, g_Allocator); fd->VertexBuffer = VK_NULL_HANDLE; } if (g_FontSampler) { vkDestroySampler(v->Device, g_FontSampler, v->Allocator); g_FontSampler = VK_NULL_HANDLE; }
if (fd->VertexBufferMemory) { vkFreeMemory (g_Device, fd->VertexBufferMemory, g_Allocator); fd->VertexBufferMemory = VK_NULL_HANDLE; } if (g_DescriptorSetLayout) { vkDestroyDescriptorSetLayout(v->Device, g_DescriptorSetLayout, v->Allocator); g_DescriptorSetLayout = VK_NULL_HANDLE; }
if (fd->IndexBuffer) { vkDestroyBuffer (g_Device, fd->IndexBuffer, g_Allocator); fd->IndexBuffer = VK_NULL_HANDLE; } if (g_PipelineLayout) { vkDestroyPipelineLayout(v->Device, g_PipelineLayout, v->Allocator); g_PipelineLayout = VK_NULL_HANDLE; }
if (fd->IndexBufferMemory) { vkFreeMemory (g_Device, fd->IndexBufferMemory, g_Allocator); fd->IndexBufferMemory = VK_NULL_HANDLE; } if (g_Pipeline) { vkDestroyPipeline(v->Device, g_Pipeline, v->Allocator); g_Pipeline = VK_NULL_HANDLE; }
}
if (g_FontView) { vkDestroyImageView(g_Device, g_FontView, g_Allocator); g_FontView = VK_NULL_HANDLE; }
if (g_FontImage) { vkDestroyImage(g_Device, g_FontImage, g_Allocator); g_FontImage = VK_NULL_HANDLE; }
if (g_FontMemory) { vkFreeMemory(g_Device, g_FontMemory, g_Allocator); g_FontMemory = VK_NULL_HANDLE; }
if (g_FontSampler) { vkDestroySampler(g_Device, g_FontSampler, g_Allocator); g_FontSampler = VK_NULL_HANDLE; }
if (g_DescriptorSetLayout) { vkDestroyDescriptorSetLayout(g_Device, g_DescriptorSetLayout, g_Allocator); g_DescriptorSetLayout = VK_NULL_HANDLE; }
if (g_PipelineLayout) { vkDestroyPipelineLayout(g_Device, g_PipelineLayout, g_Allocator); g_PipelineLayout = VK_NULL_HANDLE; }
if (g_Pipeline) { vkDestroyPipeline(g_Device, g_Pipeline, g_Allocator); g_Pipeline = VK_NULL_HANDLE; }
} }
bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass render_pass) bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass render_pass)
{ {
// Setup back-end capabilities flags
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.BackendRendererName = "imgui_impl_vulkan"; io.BackendRendererName = "imgui_impl_vulkan";
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
IM_ASSERT(info->Instance != VK_NULL_HANDLE); IM_ASSERT(info->Instance != VK_NULL_HANDLE);
IM_ASSERT(info->PhysicalDevice != VK_NULL_HANDLE); IM_ASSERT(info->PhysicalDevice != VK_NULL_HANDLE);
IM_ASSERT(info->Device != VK_NULL_HANDLE); IM_ASSERT(info->Device != VK_NULL_HANDLE);
IM_ASSERT(info->Queue != VK_NULL_HANDLE); IM_ASSERT(info->Queue != VK_NULL_HANDLE);
IM_ASSERT(info->DescriptorPool != VK_NULL_HANDLE); IM_ASSERT(info->DescriptorPool != VK_NULL_HANDLE);
IM_ASSERT(info->MinImageCount >= 2);
IM_ASSERT(info->ImageCount >= info->MinImageCount);
IM_ASSERT(render_pass != VK_NULL_HANDLE); IM_ASSERT(render_pass != VK_NULL_HANDLE);
g_Instance = info->Instance; g_VulkanInitInfo = *info;
g_PhysicalDevice = info->PhysicalDevice;
g_Device = info->Device;
g_QueueFamily = info->QueueFamily;
g_Queue = info->Queue;
g_RenderPass = render_pass; g_RenderPass = render_pass;
g_PipelineCache = info->PipelineCache;
g_DescriptorPool = info->DescriptorPool;
g_Allocator = info->Allocator;
g_CheckVkResultFn = info->CheckVkResultFn;
ImGui_ImplVulkan_CreateDeviceObjects(); ImGui_ImplVulkan_CreateDeviceObjects();
return true; return true;
@ -724,16 +826,30 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend
void ImGui_ImplVulkan_Shutdown() void ImGui_ImplVulkan_Shutdown()
{ {
ImGui_ImplVulkan_InvalidateDeviceObjects(); ImGui_ImplVulkan_DestroyDeviceObjects();
} }
void ImGui_ImplVulkan_NewFrame() void ImGui_ImplVulkan_NewFrame()
{ {
} }
void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count)
{
IM_ASSERT(min_image_count >= 2);
if (g_VulkanInitInfo.MinImageCount == min_image_count)
return;
ImGui_ImplVulkan_InitInfo* v = &g_VulkanInitInfo;
VkResult err = vkDeviceWaitIdle(v->Device);
check_vk_result(err);
ImGui_ImplVulkanH_DestroyWindowRenderBuffers(v->Device, &g_MainWindowRenderBuffers, v->Allocator);
g_VulkanInitInfo.MinImageCount = min_image_count;
}
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// Internal / Miscellaneous Vulkan Helpers // Internal / Miscellaneous Vulkan Helpers
// (Used by example's main.cpp. Used by multi-viewport features. PROBABLY NOT used by your own app.)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// You probably do NOT need to use or care about those functions. // You probably do NOT need to use or care about those functions.
// Those functions only exist because: // Those functions only exist because:
@ -741,40 +857,12 @@ void ImGui_ImplVulkan_NewFrame()
// 2) the upcoming multi-viewport feature will need them internally. // 2) the upcoming multi-viewport feature will need them internally.
// Generally we avoid exposing any kind of superfluous high-level helpers in the bindings, // Generally we avoid exposing any kind of superfluous high-level helpers in the bindings,
// but it is too much code to duplicate everywhere so we exceptionally expose them. // but it is too much code to duplicate everywhere so we exceptionally expose them.
// Your application/engine will likely already have code to setup all that stuff (swap chain, render pass, frame buffers, etc.). //
// Your engine/app will likely _already_ have code to setup all that stuff (swap chain, render pass, frame buffers, etc.).
// You may read this code to learn about Vulkan, but it is recommended you use you own custom tailored code to do equivalent work. // You may read this code to learn about Vulkan, but it is recommended you use you own custom tailored code to do equivalent work.
// (those functions do not interact with any of the state used by the regular ImGui_ImplVulkan_XXX functions) // (The ImGui_ImplVulkanH_XXX functions do not interact with any of the state used by the regular ImGui_ImplVulkan_XXX functions)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
#include <stdlib.h> // malloc
ImGui_ImplVulkanH_FrameData::ImGui_ImplVulkanH_FrameData()
{
BackbufferIndex = 0;
CommandPool = VK_NULL_HANDLE;
CommandBuffer = VK_NULL_HANDLE;
Fence = VK_NULL_HANDLE;
ImageAcquiredSemaphore = VK_NULL_HANDLE;
RenderCompleteSemaphore = VK_NULL_HANDLE;
}
ImGui_ImplVulkanH_WindowData::ImGui_ImplVulkanH_WindowData()
{
Width = Height = 0;
Swapchain = VK_NULL_HANDLE;
Surface = VK_NULL_HANDLE;
memset(&SurfaceFormat, 0, sizeof(SurfaceFormat));
PresentMode = VK_PRESENT_MODE_MAX_ENUM_KHR;
RenderPass = VK_NULL_HANDLE;
ClearEnable = true;
memset(&ClearValue, 0, sizeof(ClearValue));
BackBufferCount = 0;
memset(&BackBuffer, 0, sizeof(BackBuffer));
memset(&BackBufferView, 0, sizeof(BackBufferView));
memset(&Framebuffer, 0, sizeof(Framebuffer));
FrameIndex = 0;
}
VkSurfaceFormatKHR ImGui_ImplVulkanH_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space) VkSurfaceFormatKHR ImGui_ImplVulkanH_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space)
{ {
IM_ASSERT(request_formats != NULL); IM_ASSERT(request_formats != NULL);
@ -841,7 +929,7 @@ VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_d
return VK_PRESENT_MODE_FIFO_KHR; // Always available return VK_PRESENT_MODE_FIFO_KHR; // Always available
} }
void ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(VkPhysicalDevice physical_device, VkDevice device, uint32_t queue_family, ImGui_ImplVulkanH_WindowData* wd, const VkAllocationCallbacks* allocator) void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator)
{ {
IM_ASSERT(physical_device != VK_NULL_HANDLE && device != VK_NULL_HANDLE); IM_ASSERT(physical_device != VK_NULL_HANDLE && device != VK_NULL_HANDLE);
(void)physical_device; (void)physical_device;
@ -849,9 +937,10 @@ void ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(VkPhysicalDevice physical_
// Create Command Buffers // Create Command Buffers
VkResult err; VkResult err;
for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++) for (uint32_t i = 0; i < wd->ImageCount; i++)
{ {
ImGui_ImplVulkanH_FrameData* fd = &wd->Frames[i]; ImGui_ImplVulkanH_Frame* fd = &wd->Frames[i];
ImGui_ImplVulkanH_FrameSemaphores* fsd = &wd->FrameSemaphores[i];
{ {
VkCommandPoolCreateInfo info = {}; VkCommandPoolCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
@ -879,9 +968,9 @@ void ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(VkPhysicalDevice physical_
{ {
VkSemaphoreCreateInfo info = {}; VkSemaphoreCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
err = vkCreateSemaphore(device, &info, allocator, &fd->ImageAcquiredSemaphore); err = vkCreateSemaphore(device, &info, allocator, &fsd->ImageAcquiredSemaphore);
check_vk_result(err); check_vk_result(err);
err = vkCreateSemaphore(device, &info, allocator, &fd->RenderCompleteSemaphore); err = vkCreateSemaphore(device, &info, allocator, &fsd->RenderCompleteSemaphore);
check_vk_result(err); check_vk_result(err);
} }
} }
@ -899,24 +988,26 @@ int ImGui_ImplVulkanH_GetMinImageCountFromPresentMode(VkPresentModeKHR present_m
return 1; return 1;
} }
void ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_WindowData* wd, const VkAllocationCallbacks* allocator, int w, int h) // Also destroy old swap chain and in-flight frames data, if any.
void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count)
{ {
uint32_t min_image_count = 2; // FIXME: this should become a function parameter
VkResult err; VkResult err;
VkSwapchainKHR old_swapchain = wd->Swapchain; VkSwapchainKHR old_swapchain = wd->Swapchain;
err = vkDeviceWaitIdle(device); err = vkDeviceWaitIdle(device);
check_vk_result(err); check_vk_result(err);
// We don't use ImGui_ImplVulkanH_DestroyWindow() because we want to preserve the old swapchain to create the new one.
// Destroy old Framebuffer // Destroy old Framebuffer
for (uint32_t i = 0; i < wd->BackBufferCount; i++) for (uint32_t i = 0; i < wd->ImageCount; i++)
{ {
if (wd->BackBufferView[i]) ImGui_ImplVulkanH_DestroyFrame(device, &wd->Frames[i], allocator);
vkDestroyImageView(device, wd->BackBufferView[i], allocator); ImGui_ImplVulkanH_DestroyFrameSemaphores(device, &wd->FrameSemaphores[i], allocator);
if (wd->Framebuffer[i])
vkDestroyFramebuffer(device, wd->Framebuffer[i], allocator);
} }
wd->BackBufferCount = 0; IM_FREE(wd->Frames);
IM_FREE(wd->FrameSemaphores);
wd->Frames = NULL;
wd->FrameSemaphores = NULL;
wd->ImageCount = 0;
if (wd->RenderPass) if (wd->RenderPass)
vkDestroyRenderPass(device, wd->RenderPass, allocator); vkDestroyRenderPass(device, wd->RenderPass, allocator);
@ -960,10 +1051,21 @@ void ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(VkPhysicalDevice
} }
err = vkCreateSwapchainKHR(device, &info, allocator, &wd->Swapchain); err = vkCreateSwapchainKHR(device, &info, allocator, &wd->Swapchain);
check_vk_result(err); check_vk_result(err);
err = vkGetSwapchainImagesKHR(device, wd->Swapchain, &wd->BackBufferCount, NULL); err = vkGetSwapchainImagesKHR(device, wd->Swapchain, &wd->ImageCount, NULL);
check_vk_result(err); check_vk_result(err);
err = vkGetSwapchainImagesKHR(device, wd->Swapchain, &wd->BackBufferCount, wd->BackBuffer); VkImage backbuffers[16] = {};
IM_ASSERT(wd->ImageCount >= min_image_count);
IM_ASSERT(wd->ImageCount < IM_ARRAYSIZE(backbuffers));
err = vkGetSwapchainImagesKHR(device, wd->Swapchain, &wd->ImageCount, backbuffers);
check_vk_result(err); check_vk_result(err);
IM_ASSERT(wd->Frames == NULL);
wd->Frames = (ImGui_ImplVulkanH_Frame*)IM_ALLOC(sizeof(ImGui_ImplVulkanH_Frame) * wd->ImageCount);
wd->FrameSemaphores = (ImGui_ImplVulkanH_FrameSemaphores*)IM_ALLOC(sizeof(ImGui_ImplVulkanH_FrameSemaphores) * wd->ImageCount);
memset(wd->Frames, 0, sizeof(wd->Frames[0]) * wd->ImageCount);
memset(wd->FrameSemaphores, 0, sizeof(wd->FrameSemaphores[0]) * wd->ImageCount);
for (uint32_t i = 0; i < wd->ImageCount; i++)
wd->Frames[i].Backbuffer = backbuffers[i];
} }
if (old_swapchain) if (old_swapchain)
vkDestroySwapchainKHR(device, old_swapchain, allocator); vkDestroySwapchainKHR(device, old_swapchain, allocator);
@ -1017,10 +1119,11 @@ void ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(VkPhysicalDevice
info.components.a = VK_COMPONENT_SWIZZLE_A; info.components.a = VK_COMPONENT_SWIZZLE_A;
VkImageSubresourceRange image_range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; VkImageSubresourceRange image_range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
info.subresourceRange = image_range; info.subresourceRange = image_range;
for (uint32_t i = 0; i < wd->BackBufferCount; i++) for (uint32_t i = 0; i < wd->ImageCount; i++)
{ {
info.image = wd->BackBuffer[i]; ImGui_ImplVulkanH_Frame* fd = &wd->Frames[i];
err = vkCreateImageView(device, &info, allocator, &wd->BackBufferView[i]); info.image = fd->Backbuffer;
err = vkCreateImageView(device, &info, allocator, &fd->BackbufferView);
check_vk_result(err); check_vk_result(err);
} }
} }
@ -1036,36 +1139,80 @@ void ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(VkPhysicalDevice
info.width = wd->Width; info.width = wd->Width;
info.height = wd->Height; info.height = wd->Height;
info.layers = 1; info.layers = 1;
for (uint32_t i = 0; i < wd->BackBufferCount; i++) for (uint32_t i = 0; i < wd->ImageCount; i++)
{ {
attachment[0] = wd->BackBufferView[i]; ImGui_ImplVulkanH_Frame* fd = &wd->Frames[i];
err = vkCreateFramebuffer(device, &info, allocator, &wd->Framebuffer[i]); attachment[0] = fd->BackbufferView;
err = vkCreateFramebuffer(device, &info, allocator, &fd->Framebuffer);
check_vk_result(err); check_vk_result(err);
} }
} }
} }
void ImGui_ImplVulkanH_DestroyWindowData(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_WindowData* wd, const VkAllocationCallbacks* allocator) void ImGui_ImplVulkanH_CreateWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int width, int height, uint32_t min_image_count)
{
(void)instance;
ImGui_ImplVulkanH_CreateWindowSwapChain(physical_device, device, wd, allocator, width, height, min_image_count);
ImGui_ImplVulkanH_CreateWindowCommandBuffers(physical_device, device, wd, queue_family, allocator);
}
void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator)
{ {
vkDeviceWaitIdle(device); // FIXME: We could wait on the Queue if we had the queue in wd-> (otherwise VulkanH functions can't use globals) vkDeviceWaitIdle(device); // FIXME: We could wait on the Queue if we had the queue in wd-> (otherwise VulkanH functions can't use globals)
//vkQueueWaitIdle(g_Queue); //vkQueueWaitIdle(g_Queue);
for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++) for (uint32_t i = 0; i < wd->ImageCount; i++)
{ {
ImGui_ImplVulkanH_FrameData* fd = &wd->Frames[i]; ImGui_ImplVulkanH_DestroyFrame(device, &wd->Frames[i], allocator);
vkDestroyFence(device, fd->Fence, allocator); ImGui_ImplVulkanH_DestroyFrameSemaphores(device, &wd->FrameSemaphores[i], allocator);
vkFreeCommandBuffers(device, fd->CommandPool, 1, &fd->CommandBuffer);
vkDestroyCommandPool(device, fd->CommandPool, allocator);
vkDestroySemaphore(device, fd->ImageAcquiredSemaphore, allocator);
vkDestroySemaphore(device, fd->RenderCompleteSemaphore, allocator);
}
for (uint32_t i = 0; i < wd->BackBufferCount; i++)
{
vkDestroyImageView(device, wd->BackBufferView[i], allocator);
vkDestroyFramebuffer(device, wd->Framebuffer[i], allocator);
} }
IM_FREE(wd->Frames);
IM_FREE(wd->FrameSemaphores);
wd->Frames = NULL;
wd->FrameSemaphores = NULL;
vkDestroyRenderPass(device, wd->RenderPass, allocator); vkDestroyRenderPass(device, wd->RenderPass, allocator);
vkDestroySwapchainKHR(device, wd->Swapchain, allocator); vkDestroySwapchainKHR(device, wd->Swapchain, allocator);
vkDestroySurfaceKHR(instance, wd->Surface, allocator); vkDestroySurfaceKHR(instance, wd->Surface, allocator);
*wd = ImGui_ImplVulkanH_WindowData();
*wd = ImGui_ImplVulkanH_Window();
}
void ImGui_ImplVulkanH_DestroyFrame(VkDevice device, ImGui_ImplVulkanH_Frame* fd, const VkAllocationCallbacks* allocator)
{
vkDestroyFence(device, fd->Fence, allocator);
vkFreeCommandBuffers(device, fd->CommandPool, 1, &fd->CommandBuffer);
vkDestroyCommandPool(device, fd->CommandPool, allocator);
fd->Fence = VK_NULL_HANDLE;
fd->CommandBuffer = VK_NULL_HANDLE;
fd->CommandPool = VK_NULL_HANDLE;
vkDestroyImageView(device, fd->BackbufferView, allocator);
vkDestroyFramebuffer(device, fd->Framebuffer, allocator);
}
void ImGui_ImplVulkanH_DestroyFrameSemaphores(VkDevice device, ImGui_ImplVulkanH_FrameSemaphores* fsd, const VkAllocationCallbacks* allocator)
{
vkDestroySemaphore(device, fsd->ImageAcquiredSemaphore, allocator);
vkDestroySemaphore(device, fsd->RenderCompleteSemaphore, allocator);
fsd->ImageAcquiredSemaphore = fsd->RenderCompleteSemaphore = VK_NULL_HANDLE;
}
void ImGui_ImplVulkanH_DestroyFrameRenderBuffers(VkDevice device, ImGui_ImplVulkanH_FrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator)
{
if (buffers->VertexBuffer) { vkDestroyBuffer(device, buffers->VertexBuffer, allocator); buffers->VertexBuffer = VK_NULL_HANDLE; }
if (buffers->VertexBufferMemory) { vkFreeMemory(device, buffers->VertexBufferMemory, allocator); buffers->VertexBufferMemory = VK_NULL_HANDLE; }
if (buffers->IndexBuffer) { vkDestroyBuffer(device, buffers->IndexBuffer, allocator); buffers->IndexBuffer = VK_NULL_HANDLE; }
if (buffers->IndexBufferMemory) { vkFreeMemory(device, buffers->IndexBufferMemory, allocator); buffers->IndexBufferMemory = VK_NULL_HANDLE; }
buffers->VertexBufferSize = 0;
buffers->IndexBufferSize = 0;
}
void ImGui_ImplVulkanH_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulkanH_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator)
{
for (uint32_t n = 0; n < buffers->Count; n++)
ImGui_ImplVulkanH_DestroyFrameRenderBuffers(device, &buffers->FrameRenderBuffers[n], allocator);
IM_FREE(buffers->FrameRenderBuffers);
buffers->FrameRenderBuffers = NULL;
buffers->Index = 0;
buffers->Count = 0;
} }

View File

@ -1,6 +1,8 @@
// dear imgui: Renderer for Vulkan // dear imgui: Renderer for Vulkan
// This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..) // This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..)
// Implemented features:
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bits indices.
// Missing features: // Missing features:
// [ ] Renderer: User texture binding. Changes of ImTextureID aren't supported by this binding! See https://github.com/ocornut/imgui/pull/914 // [ ] Renderer: User texture binding. Changes of ImTextureID aren't supported by this binding! See https://github.com/ocornut/imgui/pull/914
@ -11,13 +13,19 @@
// The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification. // The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification.
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/ // IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
// Important note to the reader who wish to integrate imgui_impl_vulkan.cpp/.h in their own engine/app.
// - Common ImGui_ImplVulkan_XXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h.
// You will use those if you want to use this rendering back-end in your engine/app.
// - Helper ImGui_ImplVulkanH_XXX functions and structures are only used by this example (main.cpp) and by
// the back-end itself (imgui_impl_vulkan.cpp), but should PROBABLY NOT be used by your own engine/app code.
// Read comments in imgui_impl_vulkan.h.
#pragma once #pragma once
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#define IMGUI_VK_QUEUED_FRAMES 2 // Initialization data, for ImGui_ImplVulkan_Init()
// [Please zero-clear before use!]
// Please zero-clear before use.
struct ImGui_ImplVulkan_InitInfo struct ImGui_ImplVulkan_InitInfo
{ {
VkInstance Instance; VkInstance Instance;
@ -27,6 +35,8 @@ struct ImGui_ImplVulkan_InitInfo
VkQueue Queue; VkQueue Queue;
VkPipelineCache PipelineCache; VkPipelineCache PipelineCache;
VkDescriptorPool DescriptorPool; VkDescriptorPool DescriptorPool;
uint32_t MinImageCount; // >= 2
uint32_t ImageCount; // >= MinImageCount
const VkAllocationCallbacks* Allocator; const VkAllocationCallbacks* Allocator;
void (*CheckVkResultFn)(VkResult err); void (*CheckVkResultFn)(VkResult err);
}; };
@ -37,15 +47,13 @@ IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown();
IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame(); IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame();
IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer); IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer);
IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer); IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer);
IMGUI_IMPL_API void ImGui_ImplVulkan_InvalidateFontUploadObjects(); IMGUI_IMPL_API void ImGui_ImplVulkan_DestroyFontUploadObjects();
IMGUI_IMPL_API void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count); // To override MinImageCount after initialization (e.g. if swap chain is recreated)
// Called by ImGui_ImplVulkan_Init() might be useful elsewhere.
IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplVulkan_InvalidateDeviceObjects();
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// Internal / Miscellaneous Vulkan Helpers // Internal / Miscellaneous Vulkan Helpers
// (Used by example's main.cpp. Used by multi-viewport features. PROBABLY NOT used by your own engine/app.)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// You probably do NOT need to use or care about those functions. // You probably do NOT need to use or care about those functions.
// Those functions only exist because: // Those functions only exist because:
@ -53,36 +61,44 @@ IMGUI_IMPL_API void ImGui_ImplVulkan_InvalidateDeviceObjects();
// 2) the upcoming multi-viewport feature will need them internally. // 2) the upcoming multi-viewport feature will need them internally.
// Generally we avoid exposing any kind of superfluous high-level helpers in the bindings, // Generally we avoid exposing any kind of superfluous high-level helpers in the bindings,
// but it is too much code to duplicate everywhere so we exceptionally expose them. // but it is too much code to duplicate everywhere so we exceptionally expose them.
// Your application/engine will likely already have code to setup all that stuff (swap chain, render pass, frame buffers, etc.). //
// Your engine/app will likely _already_ have code to setup all that stuff (swap chain, render pass, frame buffers, etc.).
// You may read this code to learn about Vulkan, but it is recommended you use you own custom tailored code to do equivalent work. // You may read this code to learn about Vulkan, but it is recommended you use you own custom tailored code to do equivalent work.
// (those functions do not interact with any of the state used by the regular ImGui_ImplVulkan_XXX functions) // (The ImGui_ImplVulkanH_XXX functions do not interact with any of the state used by the regular ImGui_ImplVulkan_XXX functions)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
struct ImGui_ImplVulkanH_FrameData; struct ImGui_ImplVulkanH_Frame;
struct ImGui_ImplVulkanH_WindowData; struct ImGui_ImplVulkanH_Window;
IMGUI_IMPL_API void ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(VkPhysicalDevice physical_device, VkDevice device, uint32_t queue_family, ImGui_ImplVulkanH_WindowData* wd, const VkAllocationCallbacks* allocator); // Helpers
IMGUI_IMPL_API void ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_WindowData* wd, const VkAllocationCallbacks* allocator, int w, int h); IMGUI_IMPL_API void ImGui_ImplVulkanH_CreateWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wnd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count);
IMGUI_IMPL_API void ImGui_ImplVulkanH_DestroyWindowData(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_WindowData* wd, const VkAllocationCallbacks* allocator); IMGUI_IMPL_API void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Window* wnd, const VkAllocationCallbacks* allocator);
IMGUI_IMPL_API VkSurfaceFormatKHR ImGui_ImplVulkanH_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space); IMGUI_IMPL_API VkSurfaceFormatKHR ImGui_ImplVulkanH_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space);
IMGUI_IMPL_API VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkPresentModeKHR* request_modes, int request_modes_count); IMGUI_IMPL_API VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkPresentModeKHR* request_modes, int request_modes_count);
IMGUI_IMPL_API int ImGui_ImplVulkanH_GetMinImageCountFromPresentMode(VkPresentModeKHR present_mode); IMGUI_IMPL_API int ImGui_ImplVulkanH_GetMinImageCountFromPresentMode(VkPresentModeKHR present_mode);
// Helper structure to hold the data needed by one rendering frame // Helper structure to hold the data needed by one rendering frame
struct ImGui_ImplVulkanH_FrameData // (Used by example's main.cpp. Used by multi-viewport features. Probably NOT used by your own engine/app.)
// [Please zero-clear before use!]
struct ImGui_ImplVulkanH_Frame
{ {
uint32_t BackbufferIndex; // Keep track of recently rendered swapchain frame indices
VkCommandPool CommandPool; VkCommandPool CommandPool;
VkCommandBuffer CommandBuffer; VkCommandBuffer CommandBuffer;
VkFence Fence; VkFence Fence;
VkImage Backbuffer;
VkImageView BackbufferView;
VkFramebuffer Framebuffer;
};
struct ImGui_ImplVulkanH_FrameSemaphores
{
VkSemaphore ImageAcquiredSemaphore; VkSemaphore ImageAcquiredSemaphore;
VkSemaphore RenderCompleteSemaphore; VkSemaphore RenderCompleteSemaphore;
IMGUI_IMPL_API ImGui_ImplVulkanH_FrameData();
}; };
// Helper structure to hold the data needed by one rendering context into one OS window // Helper structure to hold the data needed by one rendering context into one OS window
struct ImGui_ImplVulkanH_WindowData // (Used by example's main.cpp. Used by multi-viewport features. Probably NOT used by your own engine/app.)
struct ImGui_ImplVulkanH_Window
{ {
int Width; int Width;
int Height; int Height;
@ -93,13 +109,17 @@ struct ImGui_ImplVulkanH_WindowData
VkRenderPass RenderPass; VkRenderPass RenderPass;
bool ClearEnable; bool ClearEnable;
VkClearValue ClearValue; VkClearValue ClearValue;
uint32_t BackBufferCount; uint32_t FrameIndex; // Current frame being rendered to (0 <= FrameIndex < FrameInFlightCount)
VkImage BackBuffer[16]; uint32_t ImageCount; // Number of simultaneous in-flight frames (returned by vkGetSwapchainImagesKHR, usually derived from min_image_count)
VkImageView BackBufferView[16]; uint32_t SemaphoreIndex; // Current set of swapchain wait semaphores we're using (needs to be distinct from per frame data)
VkFramebuffer Framebuffer[16]; ImGui_ImplVulkanH_Frame* Frames;
uint32_t FrameIndex; ImGui_ImplVulkanH_FrameSemaphores* FrameSemaphores;
ImGui_ImplVulkanH_FrameData Frames[IMGUI_VK_QUEUED_FRAMES];
IMGUI_IMPL_API ImGui_ImplVulkanH_WindowData(); ImGui_ImplVulkanH_Window()
{
memset(this, 0, sizeof(*this));
PresentMode = VK_PRESENT_MODE_MAX_ENUM_KHR;
ClearEnable = true;
}
}; };

View File

@ -5,8 +5,7 @@
// [X] Platform: Clipboard support (for Win32 this is actually part of core imgui) // [X] Platform: Clipboard support (for Win32 this is actually part of core imgui)
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE). // [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE).
// Missing features: // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
// [ ] Platform: Gamepad support (best leaving it to user application to fill io.NavInputs[] with gamepad inputs from their source of choice).
#include "imgui.h" #include "imgui.h"
#include "imgui_impl_win32.h" #include "imgui_impl_win32.h"
@ -14,10 +13,15 @@
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#endif #endif
#include <windows.h> #include <windows.h>
#include <XInput.h>
#include <tchar.h> #include <tchar.h>
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2019-05-11: Inputs: Don't filter value from WM_CHAR before calling AddInputCharacter().
// 2019-01-17: Misc: Using GetForegroundWindow()+IsChild() instead of GetActiveWindow() to be compatible with windows created in a different thread or parent.
// 2019-01-17: Inputs: Added support for mouse buttons 4 and 5 via WM_XBUTTON* messages.
// 2019-01-15: Inputs: Added support for XInput gamepads (if ImGuiConfigFlags_NavEnableGamepad is set by user application).
// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window. // 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window.
// 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor. // 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor.
// 2018-06-10: Inputs: Fixed handling of mouse wheel messages to support fine position messages (typically sent by track-pads). // 2018-06-10: Inputs: Fixed handling of mouse wheel messages to support fine position messages (typically sent by track-pads).
@ -39,6 +43,8 @@ static HWND g_hWnd = 0;
static INT64 g_Time = 0; static INT64 g_Time = 0;
static INT64 g_TicksPerSecond = 0; static INT64 g_TicksPerSecond = 0;
static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_COUNT; static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_COUNT;
static bool g_HasGamepad = false;
static bool g_WantUpdateHasGamepad = true;
// Functions // Functions
bool ImGui_ImplWin32_Init(void* hwnd) bool ImGui_ImplWin32_Init(void* hwnd)
@ -134,11 +140,63 @@ static void ImGui_ImplWin32_UpdateMousePos()
// Set mouse position // Set mouse position
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
POINT pos; POINT pos;
if (::GetActiveWindow() == g_hWnd && ::GetCursorPos(&pos)) if (HWND active_window = ::GetForegroundWindow())
if (::ScreenToClient(g_hWnd, &pos)) if (active_window == g_hWnd || ::IsChild(active_window, g_hWnd))
if (::GetCursorPos(&pos) && ::ScreenToClient(g_hWnd, &pos))
io.MousePos = ImVec2((float)pos.x, (float)pos.y); io.MousePos = ImVec2((float)pos.x, (float)pos.y);
} }
#ifdef _MSC_VER
#pragma comment(lib, "xinput")
#endif
// Gamepad navigation mapping
static void ImGui_ImplWin32_UpdateGamepads()
{
ImGuiIO& io = ImGui::GetIO();
memset(io.NavInputs, 0, sizeof(io.NavInputs));
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
return;
// Calling XInputGetState() every frame on disconnected gamepads is unfortunately too slow.
// Instead we refresh gamepad availability by calling XInputGetCapabilities() _only_ after receiving WM_DEVICECHANGE.
if (g_WantUpdateHasGamepad)
{
XINPUT_CAPABILITIES caps;
g_HasGamepad = (XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &caps) == ERROR_SUCCESS);
g_WantUpdateHasGamepad = false;
}
XINPUT_STATE xinput_state;
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
if (g_HasGamepad && XInputGetState(0, &xinput_state) == ERROR_SUCCESS)
{
const XINPUT_GAMEPAD& gamepad = xinput_state.Gamepad;
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
#define MAP_BUTTON(NAV_NO, BUTTON_ENUM) { io.NavInputs[NAV_NO] = (gamepad.wButtons & BUTTON_ENUM) ? 1.0f : 0.0f; }
#define MAP_ANALOG(NAV_NO, VALUE, V0, V1) { float vn = (float)(VALUE - V0) / (float)(V1 - V0); if (vn > 1.0f) vn = 1.0f; if (vn > 0.0f && io.NavInputs[NAV_NO] < vn) io.NavInputs[NAV_NO] = vn; }
MAP_BUTTON(ImGuiNavInput_Activate, XINPUT_GAMEPAD_A); // Cross / A
MAP_BUTTON(ImGuiNavInput_Cancel, XINPUT_GAMEPAD_B); // Circle / B
MAP_BUTTON(ImGuiNavInput_Menu, XINPUT_GAMEPAD_X); // Square / X
MAP_BUTTON(ImGuiNavInput_Input, XINPUT_GAMEPAD_Y); // Triangle / Y
MAP_BUTTON(ImGuiNavInput_DpadLeft, XINPUT_GAMEPAD_DPAD_LEFT); // D-Pad Left
MAP_BUTTON(ImGuiNavInput_DpadRight, XINPUT_GAMEPAD_DPAD_RIGHT); // D-Pad Right
MAP_BUTTON(ImGuiNavInput_DpadUp, XINPUT_GAMEPAD_DPAD_UP); // D-Pad Up
MAP_BUTTON(ImGuiNavInput_DpadDown, XINPUT_GAMEPAD_DPAD_DOWN); // D-Pad Down
MAP_BUTTON(ImGuiNavInput_FocusPrev, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB
MAP_BUTTON(ImGuiNavInput_FocusNext, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB
MAP_BUTTON(ImGuiNavInput_TweakSlow, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB
MAP_BUTTON(ImGuiNavInput_TweakFast, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB
MAP_ANALOG(ImGuiNavInput_LStickLeft, gamepad.sThumbLX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
MAP_ANALOG(ImGuiNavInput_LStickRight, gamepad.sThumbLX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
MAP_ANALOG(ImGuiNavInput_LStickUp, gamepad.sThumbLY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
MAP_ANALOG(ImGuiNavInput_LStickDown, gamepad.sThumbLY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32767);
#undef MAP_BUTTON
#undef MAP_ANALOG
}
}
void ImGui_ImplWin32_NewFrame() void ImGui_ImplWin32_NewFrame()
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
@ -172,19 +230,25 @@ void ImGui_ImplWin32_NewFrame()
g_LastMouseCursor = mouse_cursor; g_LastMouseCursor = mouse_cursor;
ImGui_ImplWin32_UpdateMouseCursor(); ImGui_ImplWin32_UpdateMouseCursor();
} }
// Update game controllers (if enabled and available)
ImGui_ImplWin32_UpdateGamepads();
} }
// Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions. // Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions.
#ifndef WM_MOUSEHWHEEL #ifndef WM_MOUSEHWHEEL
#define WM_MOUSEHWHEEL 0x020E #define WM_MOUSEHWHEEL 0x020E
#endif #endif
#ifndef DBT_DEVNODES_CHANGED
#define DBT_DEVNODES_CHANGED 0x0007
#endif
// Process Win32 mouse/keyboard inputs. // Process Win32 mouse/keyboard inputs.
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
// PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinations when dragging mouse outside of our window bounds. // PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinates when dragging mouse outside of our window bounds.
// PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag. // PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag.
IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{ {
@ -197,11 +261,13 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK:
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK:
{ {
int button = 0; int button = 0;
if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) button = 0; if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; }
if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) button = 1; if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; }
if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) button = 2; if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; }
if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == NULL) if (!ImGui::IsAnyMouseDown() && ::GetCapture() == NULL)
::SetCapture(hwnd); ::SetCapture(hwnd);
io.MouseDown[button] = true; io.MouseDown[button] = true;
@ -210,11 +276,13 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
case WM_LBUTTONUP: case WM_LBUTTONUP:
case WM_RBUTTONUP: case WM_RBUTTONUP:
case WM_MBUTTONUP: case WM_MBUTTONUP:
case WM_XBUTTONUP:
{ {
int button = 0; int button = 0;
if (msg == WM_LBUTTONUP) button = 0; if (msg == WM_LBUTTONUP) { button = 0; }
if (msg == WM_RBUTTONUP) button = 1; if (msg == WM_RBUTTONUP) { button = 1; }
if (msg == WM_MBUTTONUP) button = 2; if (msg == WM_MBUTTONUP) { button = 2; }
if (msg == WM_XBUTTONUP) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
io.MouseDown[button] = false; io.MouseDown[button] = false;
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == hwnd) if (!ImGui::IsAnyMouseDown() && ::GetCapture() == hwnd)
::ReleaseCapture(); ::ReleaseCapture();
@ -238,13 +306,16 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
return 0; return 0;
case WM_CHAR: case WM_CHAR:
// You can also use ToAscii()+GetKeyboardState() to retrieve characters. // You can also use ToAscii()+GetKeyboardState() to retrieve characters.
if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned int)wParam);
io.AddInputCharacter((unsigned short)wParam);
return 0; return 0;
case WM_SETCURSOR: case WM_SETCURSOR:
if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor()) if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor())
return 1; return 1;
return 0; return 0;
case WM_DEVICECHANGE:
if ((UINT)wParam == DBT_DEVNODES_CHANGED)
g_WantUpdateHasGamepad = true;
return 0;
} }
return 0; return 0;
} }

View File

@ -5,8 +5,7 @@
// [X] Platform: Clipboard support (for Win32 this is actually part of core imgui) // [X] Platform: Clipboard support (for Win32 this is actually part of core imgui)
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE). // [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE).
// Missing features: // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
// [ ] Platform: Gamepad support (best leaving it to user application to fill io.NavInputs[] with gamepad inputs from their source of choice).
#pragma once #pragma once

View File

@ -3,10 +3,10 @@
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure. // Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions. // You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// A) You may edit imconfig.h (and not overwrite it when updating imgui, or maintain a patch/branch with your modifications to imconfig.h) // A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/branch with your modifications to imconfig.h)
// B) or add configuration directives in your own file and compile with #define IMGUI_USER_CONFIG "myfilename.h" // B) or add configuration directives in your own file and compile with #define IMGUI_USER_CONFIG "myfilename.h"
// If you do so you need to make sure that configuration settings are defined consistently _everywhere_ dear imgui is used, which include // If you do so you need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include
// the imgui*.cpp files but also _any_ of your code that uses imgui. This is because some compile-time options have an affect on data structures. // the imgui*.cpp files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts. // Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
// Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using. // Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -17,7 +17,8 @@
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR) //#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts //#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows. //---- Define attributes of all API symbols declarations, e.g. for DLL under Windows
// Using dear imgui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility.
//#define IMGUI_API __declspec( dllexport ) //#define IMGUI_API __declspec( dllexport )
//#define IMGUI_API __declspec( dllimport ) //#define IMGUI_API __declspec( dllimport )
@ -25,13 +26,14 @@
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS //#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
//---- Don't implement demo windows functionality (ShowDemoWindow()/ShowStyleEditor()/ShowUserGuide() methods will be empty) //---- Don't implement demo windows functionality (ShowDemoWindow()/ShowStyleEditor()/ShowUserGuide() methods will be empty)
//---- It is very strongly recommended to NOT disable the demo windows during development. Please read the comments in imgui_demo.cpp. // It is very strongly recommended to NOT disable the demo windows during development. Please read the comments in imgui_demo.cpp.
//#define IMGUI_DISABLE_DEMO_WINDOWS //#define IMGUI_DISABLE_DEMO_WINDOWS
//---- Don't implement some functions to reduce linkage requirements. //---- Don't implement some functions to reduce linkage requirements.
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc.
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] Don't implement default IME handler. Won't use and link with ImmGetContext/ImmSetCompositionWindow. //#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] Don't implement default IME handler. Won't use and link with ImmGetContext/ImmSetCompositionWindow.
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function. //#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime).
//#define IMGUI_DISABLE_OSX_FUNCTIONS // [OSX] Won't use and link with any OSX function (clipboard).
//#define IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself if you don't want to link with vsnprintf. //#define IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself if you don't want to link with vsnprintf.
//#define IMGUI_DISABLE_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 wrapper so you can implement them yourself. Declare your prototypes in imconfig.h. //#define IMGUI_DISABLE_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 wrapper so you can implement them yourself. Declare your prototypes in imconfig.h.
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions(). //#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
@ -61,9 +63,18 @@
operator MyVec4() const { return MyVec4(x,y,z,w); } operator MyVec4() const { return MyVec4(x,y,z,w); }
*/ */
//---- Use 32-bit vertex indices (default is 16-bit) to allow meshes with more than 64K vertices. Render function needs to support it. //---- Using 32-bits vertex indices (default is 16-bits) is one way to allow large meshes with more than 64K vertices.
// Your renderer back-end will need to support it (most example renderer back-ends support both 16/32-bits indices).
// Another way to allow large meshes while keeping 16-bits indices is to handle ImDrawCmd::VtxOffset in your renderer.
// Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
//#define ImDrawIdx unsigned int //#define ImDrawIdx unsigned int
//---- Override ImDrawCallback signature (will need to modify renderer back-ends accordingly)
//struct ImDrawList;
//struct ImDrawCmd;
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
//#define ImDrawCallback MyImDrawCallback
//---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files. //---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
/* /*
namespace ImGui namespace ImGui

2745
imgui.cpp

File diff suppressed because it is too large Load Diff

461
imgui.h

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
// dear imgui, v1.67 // dear imgui, v1.71
// (drawing and font code) // (drawing and font code)
/* /*
@ -8,6 +8,7 @@ Index of this file:
// [SECTION] STB libraries implementation // [SECTION] STB libraries implementation
// [SECTION] Style functions // [SECTION] Style functions
// [SECTION] ImDrawList // [SECTION] ImDrawList
// [SECTION] ImDrawListSplitter
// [SECTION] ImDrawData // [SECTION] ImDrawData
// [SECTION] Helpers ShadeVertsXXX functions // [SECTION] Helpers ShadeVertsXXX functions
// [SECTION] ImFontConfig // [SECTION] ImFontConfig
@ -33,7 +34,7 @@ Index of this file:
#include <stdio.h> // vsnprintf, sscanf, printf #include <stdio.h> // vsnprintf, sscanf, printf
#if !defined(alloca) #if !defined(alloca)
#if defined(__GLIBC__) || defined(__sun) || defined(__CYGWIN__) || defined(__APPLE__) #if defined(__GLIBC__) || defined(__sun) || defined(__CYGWIN__) || defined(__APPLE__) || defined(__SWITCH__)
#include <alloca.h> // alloca (glibc uses <alloca.h>. Note that Cygwin may have _WIN32 defined, so the order matters here) #include <alloca.h> // alloca (glibc uses <alloca.h>. Note that Cygwin may have _WIN32 defined, so the order matters here)
#elif defined(_WIN32) #elif defined(_WIN32)
#include <malloc.h> // alloca #include <malloc.h> // alloca
@ -47,17 +48,20 @@ Index of this file:
// Visual Studio warnings // Visual Studio warnings
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning (disable: 4127) // condition expression is constant
#pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff) #pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff)
#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
#endif #endif
// Clang/GCC warnings with -Weverything // Clang/GCC warnings with -Weverything
#ifdef __clang__ #if defined(__clang__)
#pragma clang diagnostic ignored "-Wold-style-cast" // warning : use of old-style cast // yes, they are more terse. #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 "-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 "-Wglobal-constructors" // warning : declaration requires a global destructor // similar to above, not sure what the exact difference is.
#pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness // #pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness //
#if __has_warning("-Wzero-as-null-pointer-constant")
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning : zero as null pointer constant // some standard header variations use #define NULL 0 #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning : zero as null pointer constant // some standard header variations use #define NULL 0
#endif
#if __has_warning("-Wcomma") #if __has_warning("-Wcomma")
#pragma clang diagnostic ignored "-Wcomma" // warning : possible misuse of comma operator here // #pragma clang diagnostic ignored "-Wcomma" // warning : possible misuse of comma operator here //
#endif #endif
@ -71,6 +75,7 @@ Index of this file:
#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 "-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 #pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value
#pragma GCC diagnostic ignored "-Wstack-protector" // warning: stack protector not protecting local variables: variable length buffer
#if __GNUC__ >= 8 #if __GNUC__ >= 8
#pragma GCC diagnostic ignored "-Wclass-memaccess" // warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead #pragma GCC diagnostic ignored "-Wclass-memaccess" // warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
#endif #endif
@ -81,7 +86,7 @@ Index of this file:
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// Compile time options: // Compile time options:
//#define IMGUI_STB_NAMESPACE ImGuiStb //#define IMGUI_STB_NAMESPACE ImStb
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h" //#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h" //#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION //#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
@ -97,7 +102,7 @@ namespace IMGUI_STB_NAMESPACE
#pragma warning (disable: 4456) // declaration of 'xx' hides previous local declaration #pragma warning (disable: 4456) // declaration of 'xx' hides previous local declaration
#endif #endif
#ifdef __clang__ #if defined(__clang__)
#pragma clang diagnostic push #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-function" #pragma clang diagnostic ignored "-Wunused-function"
#pragma clang diagnostic ignored "-Wmissing-prototypes" #pragma clang diagnostic ignored "-Wmissing-prototypes"
@ -105,7 +110,7 @@ namespace IMGUI_STB_NAMESPACE
#pragma clang diagnostic ignored "-Wcast-qual" // warning : cast from 'const xxxx *' to 'xxx *' drops const qualifier // #pragma clang diagnostic ignored "-Wcast-qual" // warning : cast from 'const xxxx *' to 'xxx *' drops const qualifier //
#endif #endif
#ifdef __GNUC__ #if defined(__GNUC__)
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtype-limits" // warning: comparison is always true due to limited range of data type [-Wtype-limits] #pragma GCC diagnostic ignored "-Wtype-limits" // warning: comparison is always true due to limited range of data type [-Wtype-limits]
#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers #pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers
@ -127,8 +132,8 @@ namespace IMGUI_STB_NAMESPACE
#ifndef STB_TRUETYPE_IMPLEMENTATION // in case the user already have an implementation in the _same_ compilation unit (e.g. unity builds) #ifndef STB_TRUETYPE_IMPLEMENTATION // in case the user already have an implementation in the _same_ compilation unit (e.g. unity builds)
#ifndef IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION #ifndef IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
#define STBTT_malloc(x,u) ((void)(u), ImGui::MemAlloc(x)) #define STBTT_malloc(x,u) ((void)(u), IM_ALLOC(x))
#define STBTT_free(x,u) ((void)(u), ImGui::MemFree(x)) #define STBTT_free(x,u) ((void)(u), IM_FREE(x))
#define STBTT_assert(x) IM_ASSERT(x) #define STBTT_assert(x) IM_ASSERT(x)
#define STBTT_fmod(x,y) ImFmod(x,y) #define STBTT_fmod(x,y) ImFmod(x,y)
#define STBTT_sqrt(x) ImSqrt(x) #define STBTT_sqrt(x) ImSqrt(x)
@ -148,20 +153,20 @@ namespace IMGUI_STB_NAMESPACE
#endif #endif
#endif #endif
#ifdef __GNUC__ #if defined(__GNUC__)
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
#ifdef __clang__ #if defined(__clang__)
#pragma clang diagnostic pop #pragma clang diagnostic pop
#endif #endif
#ifdef _MSC_VER #if defined(_MSC_VER)
#pragma warning (pop) #pragma warning (pop)
#endif #endif
#ifdef IMGUI_STB_NAMESPACE #ifdef IMGUI_STB_NAMESPACE
} // namespace ImGuiStb } // namespace ImStb
using namespace IMGUI_STB_NAMESPACE; using namespace IMGUI_STB_NAMESPACE;
#endif #endif
@ -345,6 +350,7 @@ ImDrawListSharedData::ImDrawListSharedData()
FontSize = 0.0f; FontSize = 0.0f;
CurveTessellationTol = 0.0f; CurveTessellationTol = 0.0f;
ClipRectFullscreen = ImVec4(-8192.0f, -8192.0f, +8192.0f, +8192.0f); ClipRectFullscreen = ImVec4(-8192.0f, -8192.0f, +8192.0f, +8192.0f);
InitialFlags = ImDrawListFlags_None;
// Const data // Const data
for (int i = 0; i < IM_ARRAYSIZE(CircleVtx12); i++) for (int i = 0; i < IM_ARRAYSIZE(CircleVtx12); i++)
@ -359,16 +365,15 @@ void ImDrawList::Clear()
CmdBuffer.resize(0); CmdBuffer.resize(0);
IdxBuffer.resize(0); IdxBuffer.resize(0);
VtxBuffer.resize(0); VtxBuffer.resize(0);
Flags = ImDrawListFlags_AntiAliasedLines | ImDrawListFlags_AntiAliasedFill; Flags = _Data->InitialFlags;
_VtxCurrentOffset = 0;
_VtxCurrentIdx = 0; _VtxCurrentIdx = 0;
_VtxWritePtr = NULL; _VtxWritePtr = NULL;
_IdxWritePtr = NULL; _IdxWritePtr = NULL;
_ClipRectStack.resize(0); _ClipRectStack.resize(0);
_TextureIdStack.resize(0); _TextureIdStack.resize(0);
_Path.resize(0); _Path.resize(0);
_ChannelsCurrent = 0; _Splitter.Clear();
_ChannelsCount = 1;
// NB: Do not clear channels so our allocations are re-used after the first frame.
} }
void ImDrawList::ClearFreeMemory() void ImDrawList::ClearFreeMemory()
@ -382,15 +387,7 @@ void ImDrawList::ClearFreeMemory()
_ClipRectStack.clear(); _ClipRectStack.clear();
_TextureIdStack.clear(); _TextureIdStack.clear();
_Path.clear(); _Path.clear();
_ChannelsCurrent = 0; _Splitter.ClearFreeMemory();
_ChannelsCount = 1;
for (int i = 0; i < _Channels.Size; i++)
{
if (i == 0) memset(&_Channels[0], 0, sizeof(_Channels[0])); // channel 0 is a copy of CmdBuffer/IdxBuffer, don't destruct again
_Channels[i].CmdBuffer.clear();
_Channels[i].IdxBuffer.clear();
}
_Channels.clear();
} }
ImDrawList* ImDrawList::CloneOutput() const ImDrawList* ImDrawList::CloneOutput() const
@ -405,13 +402,15 @@ ImDrawList* ImDrawList::CloneOutput() const
// Using macros because C++ is a terrible language, we want guaranteed inline, no code in header, and no overhead in Debug builds // Using macros because C++ is a terrible language, we want guaranteed inline, no code in header, and no overhead in Debug builds
#define GetCurrentClipRect() (_ClipRectStack.Size ? _ClipRectStack.Data[_ClipRectStack.Size-1] : _Data->ClipRectFullscreen) #define GetCurrentClipRect() (_ClipRectStack.Size ? _ClipRectStack.Data[_ClipRectStack.Size-1] : _Data->ClipRectFullscreen)
#define GetCurrentTextureId() (_TextureIdStack.Size ? _TextureIdStack.Data[_TextureIdStack.Size-1] : NULL) #define GetCurrentTextureId() (_TextureIdStack.Size ? _TextureIdStack.Data[_TextureIdStack.Size-1] : (ImTextureID)NULL)
void ImDrawList::AddDrawCmd() void ImDrawList::AddDrawCmd()
{ {
ImDrawCmd draw_cmd; ImDrawCmd draw_cmd;
draw_cmd.ClipRect = GetCurrentClipRect(); draw_cmd.ClipRect = GetCurrentClipRect();
draw_cmd.TextureId = GetCurrentTextureId(); draw_cmd.TextureId = GetCurrentTextureId();
draw_cmd.VtxOffset = _VtxCurrentOffset;
draw_cmd.IdxOffset = IdxBuffer.Size;
IM_ASSERT(draw_cmd.ClipRect.x <= draw_cmd.ClipRect.z && draw_cmd.ClipRect.y <= draw_cmd.ClipRect.w); IM_ASSERT(draw_cmd.ClipRect.x <= draw_cmd.ClipRect.z && draw_cmd.ClipRect.y <= draw_cmd.ClipRect.w);
CmdBuffer.push_back(draw_cmd); CmdBuffer.push_back(draw_cmd);
@ -518,88 +517,17 @@ void ImDrawList::PopTextureID()
UpdateTextureID(); UpdateTextureID();
} }
void ImDrawList::ChannelsSplit(int channels_count)
{
IM_ASSERT(_ChannelsCurrent == 0 && _ChannelsCount == 1);
int old_channels_count = _Channels.Size;
if (old_channels_count < channels_count)
_Channels.resize(channels_count);
_ChannelsCount = channels_count;
// _Channels[] (24/32 bytes each) hold storage that we'll swap with this->_CmdBuffer/_IdxBuffer
// The content of _Channels[0] at this point doesn't matter. We clear it to make state tidy in a debugger but we don't strictly need to.
// When we switch to the next channel, we'll copy _CmdBuffer/_IdxBuffer into _Channels[0] and then _Channels[1] into _CmdBuffer/_IdxBuffer
memset(&_Channels[0], 0, sizeof(ImDrawChannel));
for (int i = 1; i < channels_count; i++)
{
if (i >= old_channels_count)
{
IM_PLACEMENT_NEW(&_Channels[i]) ImDrawChannel();
}
else
{
_Channels[i].CmdBuffer.resize(0);
_Channels[i].IdxBuffer.resize(0);
}
if (_Channels[i].CmdBuffer.Size == 0)
{
ImDrawCmd draw_cmd;
draw_cmd.ClipRect = _ClipRectStack.back();
draw_cmd.TextureId = _TextureIdStack.back();
_Channels[i].CmdBuffer.push_back(draw_cmd);
}
}
}
void ImDrawList::ChannelsMerge()
{
// Note that we never use or rely on channels.Size because it is merely a buffer that we never shrink back to 0 to keep all sub-buffers ready for use.
if (_ChannelsCount <= 1)
return;
ChannelsSetCurrent(0);
if (CmdBuffer.Size && CmdBuffer.back().ElemCount == 0)
CmdBuffer.pop_back();
int new_cmd_buffer_count = 0, new_idx_buffer_count = 0;
for (int i = 1; i < _ChannelsCount; i++)
{
ImDrawChannel& ch = _Channels[i];
if (ch.CmdBuffer.Size && ch.CmdBuffer.back().ElemCount == 0)
ch.CmdBuffer.pop_back();
new_cmd_buffer_count += ch.CmdBuffer.Size;
new_idx_buffer_count += ch.IdxBuffer.Size;
}
CmdBuffer.resize(CmdBuffer.Size + new_cmd_buffer_count);
IdxBuffer.resize(IdxBuffer.Size + new_idx_buffer_count);
ImDrawCmd* cmd_write = CmdBuffer.Data + CmdBuffer.Size - new_cmd_buffer_count;
_IdxWritePtr = IdxBuffer.Data + IdxBuffer.Size - new_idx_buffer_count;
for (int i = 1; i < _ChannelsCount; i++)
{
ImDrawChannel& ch = _Channels[i];
if (int sz = ch.CmdBuffer.Size) { memcpy(cmd_write, ch.CmdBuffer.Data, sz * sizeof(ImDrawCmd)); cmd_write += sz; }
if (int sz = ch.IdxBuffer.Size) { memcpy(_IdxWritePtr, ch.IdxBuffer.Data, sz * sizeof(ImDrawIdx)); _IdxWritePtr += sz; }
}
UpdateClipRect(); // We call this instead of AddDrawCmd(), so that empty channels won't produce an extra draw call.
_ChannelsCount = 1;
}
void ImDrawList::ChannelsSetCurrent(int idx)
{
IM_ASSERT(idx < _ChannelsCount);
if (_ChannelsCurrent == idx) return;
memcpy(&_Channels.Data[_ChannelsCurrent].CmdBuffer, &CmdBuffer, sizeof(CmdBuffer)); // copy 12 bytes, four times
memcpy(&_Channels.Data[_ChannelsCurrent].IdxBuffer, &IdxBuffer, sizeof(IdxBuffer));
_ChannelsCurrent = idx;
memcpy(&CmdBuffer, &_Channels.Data[_ChannelsCurrent].CmdBuffer, sizeof(CmdBuffer));
memcpy(&IdxBuffer, &_Channels.Data[_ChannelsCurrent].IdxBuffer, sizeof(IdxBuffer));
_IdxWritePtr = IdxBuffer.Data + IdxBuffer.Size;
}
// NB: this can be called with negative count for removing primitives (as long as the result does not underflow) // NB: this can be called with negative count for removing primitives (as long as the result does not underflow)
void ImDrawList::PrimReserve(int idx_count, int vtx_count) void ImDrawList::PrimReserve(int idx_count, int vtx_count)
{ {
// Large mesh support (when enabled)
if (sizeof(ImDrawIdx) == 2 && (_VtxCurrentIdx + vtx_count >= (1 << 16)) && (Flags & ImDrawListFlags_AllowVtxOffset))
{
_VtxCurrentOffset = VtxBuffer.Size;
_VtxCurrentIdx = 0;
AddDrawCmd();
}
ImDrawCmd& draw_cmd = CmdBuffer.Data[CmdBuffer.Size-1]; ImDrawCmd& draw_cmd = CmdBuffer.Data[CmdBuffer.Size-1];
draw_cmd.ElemCount += idx_count; draw_cmd.ElemCount += idx_count;
@ -660,7 +588,7 @@ void ImDrawList::PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, c
// On AddPolyline() and AddConvexPolyFilled() we intentionally avoid using ImVec2 and superflous function calls to optimize debug/non-inlined builds. // On AddPolyline() and AddConvexPolyFilled() we intentionally avoid using ImVec2 and superflous function calls to optimize debug/non-inlined builds.
// Those macros expects l-values. // Those macros expects l-values.
#define IM_NORMALIZE2F_OVER_ZERO(VX,VY) { float d2 = VX*VX + VY*VY; if (d2 > 0.0f) { float inv_len = 1.0f / ImSqrt(d2); VX *= inv_len; VY *= inv_len; } } #define IM_NORMALIZE2F_OVER_ZERO(VX,VY) { float d2 = VX*VX + VY*VY; if (d2 > 0.0f) { float inv_len = 1.0f / ImSqrt(d2); VX *= inv_len; VY *= inv_len; } }
#define IM_NORMALIZE2F_OVER_EPSILON_CLAMP(VX,VY,EPS,INVLENMAX) { float d2 = VX*VX + VY*VY; if (d2 > EPS) { float inv_len = 1.0f / ImSqrt(d2); if (inv_len > INVLENMAX) inv_len = INVLENMAX; VX *= inv_len; VY *= inv_len; } } #define IM_FIXNORMAL2F(VX,VY) { float d2 = VX*VX + VY*VY; if (d2 < 0.5f) d2 = 0.5f; float inv_lensq = 1.0f / d2; VX *= inv_lensq; VY *= inv_lensq; }
// TODO: Thickness anti-aliased lines cap are missing their AA fringe. // TODO: Thickness anti-aliased lines cap are missing their AA fringe.
// We avoid using the ImVec2 math operators here to reduce cost to a minimum for debug/non-inlined builds. // We avoid using the ImVec2 math operators here to reduce cost to a minimum for debug/non-inlined builds.
@ -687,7 +615,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
PrimReserve(idx_count, vtx_count); PrimReserve(idx_count, vtx_count);
// Temporary buffer // Temporary buffer
ImVec2* temp_normals = (ImVec2*)alloca(points_count * (thick_line ? 5 : 3) * sizeof(ImVec2)); ImVec2* temp_normals = (ImVec2*)alloca(points_count * (thick_line ? 5 : 3) * sizeof(ImVec2)); //-V630
ImVec2* temp_points = temp_normals + points_count; ImVec2* temp_points = temp_normals + points_count;
for (int i1 = 0; i1 < count; i1++) for (int i1 = 0; i1 < count; i1++)
@ -722,7 +650,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
// Average normals // Average normals
float dm_x = (temp_normals[i1].x + temp_normals[i2].x) * 0.5f; float dm_x = (temp_normals[i1].x + temp_normals[i2].x) * 0.5f;
float dm_y = (temp_normals[i1].y + temp_normals[i2].y) * 0.5f; float dm_y = (temp_normals[i1].y + temp_normals[i2].y) * 0.5f;
IM_NORMALIZE2F_OVER_EPSILON_CLAMP(dm_x, dm_y, 0.000001f, 100.0f) IM_FIXNORMAL2F(dm_x, dm_y)
dm_x *= AA_SIZE; dm_x *= AA_SIZE;
dm_y *= AA_SIZE; dm_y *= AA_SIZE;
@ -777,7 +705,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
// Average normals // Average normals
float dm_x = (temp_normals[i1].x + temp_normals[i2].x) * 0.5f; float dm_x = (temp_normals[i1].x + temp_normals[i2].x) * 0.5f;
float dm_y = (temp_normals[i1].y + temp_normals[i2].y) * 0.5f; float dm_y = (temp_normals[i1].y + temp_normals[i2].y) * 0.5f;
IM_NORMALIZE2F_OVER_EPSILON_CLAMP(dm_x, dm_y, 0.000001f, 100.0f); IM_FIXNORMAL2F(dm_x, dm_y);
float dm_out_x = dm_x * (half_inner_thickness + AA_SIZE); float dm_out_x = dm_x * (half_inner_thickness + AA_SIZE);
float dm_out_y = dm_y * (half_inner_thickness + AA_SIZE); float dm_out_y = dm_y * (half_inner_thickness + AA_SIZE);
float dm_in_x = dm_x * half_inner_thickness; float dm_in_x = dm_x * half_inner_thickness;
@ -878,7 +806,7 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun
} }
// Compute normals // Compute normals
ImVec2* temp_normals = (ImVec2*)alloca(points_count * sizeof(ImVec2)); ImVec2* temp_normals = (ImVec2*)alloca(points_count * sizeof(ImVec2)); //-V630
for (int i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++) for (int i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++)
{ {
const ImVec2& p0 = points[i0]; const ImVec2& p0 = points[i0];
@ -897,7 +825,7 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun
const ImVec2& n1 = temp_normals[i1]; const ImVec2& n1 = temp_normals[i1];
float dm_x = (n0.x + n1.x) * 0.5f; float dm_x = (n0.x + n1.x) * 0.5f;
float dm_y = (n0.y + n1.y) * 0.5f; float dm_y = (n0.y + n1.y) * 0.5f;
IM_NORMALIZE2F_OVER_EPSILON_CLAMP(dm_x, dm_y, 0.000001f, 100.0f); IM_FIXNORMAL2F(dm_x, dm_y);
dm_x *= AA_SIZE * 0.5f; dm_x *= AA_SIZE * 0.5f;
dm_y *= AA_SIZE * 0.5f; dm_y *= AA_SIZE * 0.5f;
@ -955,6 +883,9 @@ void ImDrawList::PathArcTo(const ImVec2& centre, float radius, float a_min, floa
_Path.push_back(centre); _Path.push_back(centre);
return; return;
} }
// Note that we are adding a point at both a_min and a_max.
// If you are trying to draw a full closed circle you don't want the overlapping points!
_Path.reserve(_Path.Size + (num_segments + 1)); _Path.reserve(_Path.Size + (num_segments + 1));
for (int i = 0; i <= num_segments; i++) for (int i = 0; i <= num_segments; i++)
{ {
@ -1138,21 +1069,23 @@ void ImDrawList::AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec
void ImDrawList::AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments, float thickness) void ImDrawList::AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments, float thickness)
{ {
if ((col & IM_COL32_A_MASK) == 0) if ((col & IM_COL32_A_MASK) == 0 || num_segments <= 2)
return; return;
// Because we are filling a closed shape we remove 1 from the count of segments/points
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.5f, 0.0f, a_max, num_segments); PathArcTo(centre, radius-0.5f, 0.0f, a_max, num_segments - 1);
PathStroke(col, true, thickness); 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)
{ {
if ((col & IM_COL32_A_MASK) == 0) if ((col & IM_COL32_A_MASK) == 0 || num_segments <= 2)
return; return;
// Because we are filling a closed shape we remove 1 from the count of segments/points
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.0f, a_max, num_segments - 1);
PathFillConvex(col); PathFillConvex(col);
} }
@ -1257,6 +1190,133 @@ void ImDrawList::AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, c
PopTextureID(); PopTextureID();
} }
//-----------------------------------------------------------------------------
// ImDrawListSplitter
//-----------------------------------------------------------------------------
// FIXME: This may be a little confusing, trying to be a little too low-level/optimal instead of just doing vector swap..
//-----------------------------------------------------------------------------
void ImDrawListSplitter::ClearFreeMemory()
{
for (int i = 0; i < _Channels.Size; i++)
{
if (i == _Current)
memset(&_Channels[i], 0, sizeof(_Channels[i])); // Current channel is a copy of CmdBuffer/IdxBuffer, don't destruct again
_Channels[i]._CmdBuffer.clear();
_Channels[i]._IdxBuffer.clear();
}
_Current = 0;
_Count = 1;
_Channels.clear();
}
void ImDrawListSplitter::Split(ImDrawList* draw_list, int channels_count)
{
IM_ASSERT(_Current == 0 && _Count <= 1);
int old_channels_count = _Channels.Size;
if (old_channels_count < channels_count)
_Channels.resize(channels_count);
_Count = channels_count;
// Channels[] (24/32 bytes each) hold storage that we'll swap with draw_list->_CmdBuffer/_IdxBuffer
// The content of Channels[0] at this point doesn't matter. We clear it to make state tidy in a debugger but we don't strictly need to.
// When we switch to the next channel, we'll copy draw_list->_CmdBuffer/_IdxBuffer into Channels[0] and then Channels[1] into draw_list->CmdBuffer/_IdxBuffer
memset(&_Channels[0], 0, sizeof(ImDrawChannel));
for (int i = 1; i < channels_count; i++)
{
if (i >= old_channels_count)
{
IM_PLACEMENT_NEW(&_Channels[i]) ImDrawChannel();
}
else
{
_Channels[i]._CmdBuffer.resize(0);
_Channels[i]._IdxBuffer.resize(0);
}
if (_Channels[i]._CmdBuffer.Size == 0)
{
ImDrawCmd draw_cmd;
draw_cmd.ClipRect = draw_list->_ClipRectStack.back();
draw_cmd.TextureId = draw_list->_TextureIdStack.back();
_Channels[i]._CmdBuffer.push_back(draw_cmd);
}
}
}
static inline bool CanMergeDrawCommands(ImDrawCmd* a, ImDrawCmd* b)
{
return memcmp(&a->ClipRect, &b->ClipRect, sizeof(a->ClipRect)) == 0 && a->TextureId == b->TextureId && a->VtxOffset == b->VtxOffset && !a->UserCallback && !b->UserCallback;
}
void ImDrawListSplitter::Merge(ImDrawList* draw_list)
{
// Note that we never use or rely on channels.Size because it is merely a buffer that we never shrink back to 0 to keep all sub-buffers ready for use.
if (_Count <= 1)
return;
SetCurrentChannel(draw_list, 0);
if (draw_list->CmdBuffer.Size != 0 && draw_list->CmdBuffer.back().ElemCount == 0)
draw_list->CmdBuffer.pop_back();
// Calculate our final buffer sizes. Also fix the incorrect IdxOffset values in each command.
int new_cmd_buffer_count = 0;
int new_idx_buffer_count = 0;
ImDrawCmd* last_cmd = (_Count > 0 && _Channels[0]._CmdBuffer.Size > 0) ? &_Channels[0]._CmdBuffer.back() : NULL;
int idx_offset = last_cmd ? last_cmd->IdxOffset + last_cmd->ElemCount : 0;
for (int i = 1; i < _Count; i++)
{
ImDrawChannel& ch = _Channels[i];
if (ch._CmdBuffer.Size > 0 && ch._CmdBuffer.back().ElemCount == 0)
ch._CmdBuffer.pop_back();
if (ch._CmdBuffer.Size > 0 && last_cmd != NULL && CanMergeDrawCommands(last_cmd, &ch._CmdBuffer[0]))
{
// Merge previous channel last draw command with current channel first draw command if matching.
last_cmd->ElemCount += ch._CmdBuffer[0].ElemCount;
idx_offset += ch._CmdBuffer[0].ElemCount;
ch._CmdBuffer.erase(ch._CmdBuffer.Data);
}
if (ch._CmdBuffer.Size > 0)
last_cmd = &ch._CmdBuffer.back();
new_cmd_buffer_count += ch._CmdBuffer.Size;
new_idx_buffer_count += ch._IdxBuffer.Size;
for (int cmd_n = 0; cmd_n < ch._CmdBuffer.Size; cmd_n++)
{
ch._CmdBuffer.Data[cmd_n].IdxOffset = idx_offset;
idx_offset += ch._CmdBuffer.Data[cmd_n].ElemCount;
}
}
draw_list->CmdBuffer.resize(draw_list->CmdBuffer.Size + new_cmd_buffer_count);
draw_list->IdxBuffer.resize(draw_list->IdxBuffer.Size + new_idx_buffer_count);
// Write commands and indices in order (they are fairly small structures, we don't copy vertices only indices)
ImDrawCmd* cmd_write = draw_list->CmdBuffer.Data + draw_list->CmdBuffer.Size - new_cmd_buffer_count;
ImDrawIdx* idx_write = draw_list->IdxBuffer.Data + draw_list->IdxBuffer.Size - new_idx_buffer_count;
for (int i = 1; i < _Count; i++)
{
ImDrawChannel& ch = _Channels[i];
if (int sz = ch._CmdBuffer.Size) { memcpy(cmd_write, ch._CmdBuffer.Data, sz * sizeof(ImDrawCmd)); cmd_write += sz; }
if (int sz = ch._IdxBuffer.Size) { memcpy(idx_write, ch._IdxBuffer.Data, sz * sizeof(ImDrawIdx)); idx_write += sz; }
}
draw_list->_IdxWritePtr = idx_write;
draw_list->UpdateClipRect(); // We call this instead of AddDrawCmd(), so that empty channels won't produce an extra draw call.
_Count = 1;
}
void ImDrawListSplitter::SetCurrentChannel(ImDrawList* draw_list, int idx)
{
IM_ASSERT(idx < _Count);
if (_Current == idx)
return;
// Overwrite ImVector (12/16 bytes), four times. This is merely a silly optimization instead of doing .swap()
memcpy(&_Channels.Data[_Current]._CmdBuffer, &draw_list->CmdBuffer, sizeof(draw_list->CmdBuffer));
memcpy(&_Channels.Data[_Current]._IdxBuffer, &draw_list->IdxBuffer, sizeof(draw_list->IdxBuffer));
_Current = idx;
memcpy(&draw_list->CmdBuffer, &_Channels.Data[idx]._CmdBuffer, sizeof(draw_list->CmdBuffer));
memcpy(&draw_list->IdxBuffer, &_Channels.Data[idx]._IdxBuffer, sizeof(draw_list->IdxBuffer));
draw_list->_IdxWritePtr = draw_list->IdxBuffer.Data + draw_list->IdxBuffer.Size;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] ImDrawData // [SECTION] ImDrawData
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -1280,8 +1340,10 @@ void ImDrawData::DeIndexAllBuffers()
} }
} }
// Helper to scale the ClipRect field of each ImDrawCmd. Use if your final output buffer is at a different scale than ImGui expects, or if there is a difference between your window resolution and framebuffer resolution. // Helper to scale the ClipRect field of each ImDrawCmd.
void ImDrawData::ScaleClipRects(const ImVec2& scale) // Use if your final output buffer is at a different scale than draw_data->DisplaySize,
// or if there is a difference between your window resolution and framebuffer resolution.
void ImDrawData::ScaleClipRects(const ImVec2& fb_scale)
{ {
for (int i = 0; i < CmdListsCount; i++) for (int i = 0; i < CmdListsCount; i++)
{ {
@ -1289,7 +1351,7 @@ void ImDrawData::ScaleClipRects(const ImVec2& scale)
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{ {
ImDrawCmd* cmd = &cmd_list->CmdBuffer[cmd_i]; ImDrawCmd* cmd = &cmd_list->CmdBuffer[cmd_i];
cmd->ClipRect = ImVec4(cmd->ClipRect.x * scale.x, cmd->ClipRect.y * scale.y, cmd->ClipRect.z * scale.x, cmd->ClipRect.w * scale.y); cmd->ClipRect = ImVec4(cmd->ClipRect.x * fb_scale.x, cmd->ClipRect.y * fb_scale.y, cmd->ClipRect.z * fb_scale.x, cmd->ClipRect.w * fb_scale.y);
} }
} }
} }
@ -1352,7 +1414,7 @@ ImFontConfig::ImFontConfig()
FontDataOwnedByAtlas = true; FontDataOwnedByAtlas = true;
FontNo = 0; FontNo = 0;
SizePixels = 0.0f; SizePixels = 0.0f;
OversampleH = 3; OversampleH = 3; // FIXME: 2 may be a better default?
OversampleV = 1; OversampleV = 1;
PixelSnapH = false; PixelSnapH = false;
GlyphExtraSpacing = ImVec2(0.0f, 0.0f); GlyphExtraSpacing = ImVec2(0.0f, 0.0f);
@ -1372,7 +1434,7 @@ ImFontConfig::ImFontConfig()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// A work of art lies ahead! (. = white layer, X = black layer, others are blank) // A work of art lies ahead! (. = white layer, X = black layer, others are blank)
// The white texels on the top left are the ones we'll use everywhere in ImGui to render filled shapes. // The white texels on the top left are the ones we'll use everywhere in Dear ImGui to render filled shapes.
const int FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF = 108; const int FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF = 108;
const int FONT_ATLAS_DEFAULT_TEX_DATA_H = 27; const int FONT_ATLAS_DEFAULT_TEX_DATA_H = 27;
const unsigned int FONT_ATLAS_DEFAULT_TEX_DATA_ID = 0x80000000; const unsigned int FONT_ATLAS_DEFAULT_TEX_DATA_ID = 0x80000000;
@ -1449,7 +1511,7 @@ void ImFontAtlas::ClearInputData()
for (int i = 0; i < ConfigData.Size; i++) for (int i = 0; i < ConfigData.Size; i++)
if (ConfigData[i].FontData && ConfigData[i].FontDataOwnedByAtlas) if (ConfigData[i].FontData && ConfigData[i].FontDataOwnedByAtlas)
{ {
ImGui::MemFree(ConfigData[i].FontData); IM_FREE(ConfigData[i].FontData);
ConfigData[i].FontData = NULL; ConfigData[i].FontData = NULL;
} }
@ -1470,9 +1532,9 @@ void ImFontAtlas::ClearTexData()
{ {
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!"); IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!");
if (TexPixelsAlpha8) if (TexPixelsAlpha8)
ImGui::MemFree(TexPixelsAlpha8); IM_FREE(TexPixelsAlpha8);
if (TexPixelsRGBA32) if (TexPixelsRGBA32)
ImGui::MemFree(TexPixelsRGBA32); IM_FREE(TexPixelsRGBA32);
TexPixelsAlpha8 = NULL; TexPixelsAlpha8 = NULL;
TexPixelsRGBA32 = NULL; TexPixelsRGBA32 = NULL;
} }
@ -1518,7 +1580,7 @@ void ImFontAtlas::GetTexDataAsRGBA32(unsigned char** out_pixels, int* out_wid
GetTexDataAsAlpha8(&pixels, NULL, NULL); GetTexDataAsAlpha8(&pixels, NULL, NULL);
if (pixels) if (pixels)
{ {
TexPixelsRGBA32 = (unsigned int*)ImGui::MemAlloc((size_t)(TexWidth * TexHeight * 4)); TexPixelsRGBA32 = (unsigned int*)IM_ALLOC((size_t)TexWidth * (size_t)TexHeight * 4);
const unsigned char* src = pixels; const unsigned char* src = pixels;
unsigned int* dst = TexPixelsRGBA32; unsigned int* dst = TexPixelsRGBA32;
for (int n = TexWidth * TexHeight; n > 0; n--) for (int n = TexWidth * TexHeight; n > 0; n--)
@ -1550,7 +1612,7 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg)
new_font_cfg.DstFont = Fonts.back(); new_font_cfg.DstFont = Fonts.back();
if (!new_font_cfg.FontDataOwnedByAtlas) if (!new_font_cfg.FontDataOwnedByAtlas)
{ {
new_font_cfg.FontData = ImGui::MemAlloc(new_font_cfg.FontDataSize); new_font_cfg.FontData = IM_ALLOC(new_font_cfg.FontDataSize);
new_font_cfg.FontDataOwnedByAtlas = true; new_font_cfg.FontDataOwnedByAtlas = true;
memcpy(new_font_cfg.FontData, font_cfg->FontData, (size_t)new_font_cfg.FontDataSize); memcpy(new_font_cfg.FontData, font_cfg->FontData, (size_t)new_font_cfg.FontDataSize);
} }
@ -1585,8 +1647,10 @@ ImFont* ImFontAtlas::AddFontDefault(const ImFontConfig* font_cfg_template)
font_cfg.OversampleH = font_cfg.OversampleV = 1; font_cfg.OversampleH = font_cfg.OversampleV = 1;
font_cfg.PixelSnapH = true; font_cfg.PixelSnapH = true;
} }
if (font_cfg.Name[0] == '\0') strcpy(font_cfg.Name, "ProggyClean.ttf, 13px"); if (font_cfg.SizePixels <= 0.0f)
if (font_cfg.SizePixels <= 0.0f) font_cfg.SizePixels = 13.0f; font_cfg.SizePixels = 13.0f * 1.0f;
if (font_cfg.Name[0] == '\0')
ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "ProggyClean.ttf, %dpx", (int)font_cfg.SizePixels);
const char* ttf_compressed_base85 = GetDefaultCompressedFontDataTTFBase85(); const char* ttf_compressed_base85 = GetDefaultCompressedFontDataTTFBase85();
const ImWchar* glyph_ranges = font_cfg.GlyphRanges != NULL ? font_cfg.GlyphRanges : GetGlyphRangesDefault(); const ImWchar* glyph_ranges = font_cfg.GlyphRanges != NULL ? font_cfg.GlyphRanges : GetGlyphRangesDefault();
@ -1633,7 +1697,7 @@ ImFont* ImFontAtlas::AddFontFromMemoryTTF(void* ttf_data, int ttf_size, float si
ImFont* ImFontAtlas::AddFontFromMemoryCompressedTTF(const void* compressed_ttf_data, int compressed_ttf_size, float size_pixels, const ImFontConfig* font_cfg_template, const ImWchar* glyph_ranges) ImFont* ImFontAtlas::AddFontFromMemoryCompressedTTF(const void* compressed_ttf_data, int compressed_ttf_size, float size_pixels, const ImFontConfig* font_cfg_template, const ImWchar* glyph_ranges)
{ {
const unsigned int buf_decompressed_size = stb_decompress_length((const unsigned char*)compressed_ttf_data); const unsigned int buf_decompressed_size = stb_decompress_length((const unsigned char*)compressed_ttf_data);
unsigned char* buf_decompressed_data = (unsigned char *)ImGui::MemAlloc(buf_decompressed_size); unsigned char* buf_decompressed_data = (unsigned char *)IM_ALLOC(buf_decompressed_size);
stb_decompress(buf_decompressed_data, (const unsigned char*)compressed_ttf_data, (unsigned int)compressed_ttf_size); stb_decompress(buf_decompressed_data, (const unsigned char*)compressed_ttf_data, (unsigned int)compressed_ttf_size);
ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig(); ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig();
@ -1645,10 +1709,10 @@ ImFont* ImFontAtlas::AddFontFromMemoryCompressedTTF(const void* compressed_ttf_d
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((size_t)compressed_ttf_size); void* compressed_ttf = IM_ALLOC((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); IM_FREE(compressed_ttf);
return font; return font;
} }
@ -1767,7 +1831,7 @@ static void UnpackBoolVectorToFlatIndexList(const ImBoolVector* in, ImVector<int
for (const int* it = it_begin; it < it_end; it++) for (const int* it = it_begin; it < it_end; it++)
if (int entries_32 = *it) if (int entries_32 = *it)
for (int bit_n = 0; bit_n < 32; bit_n++) for (int bit_n = 0; bit_n < 32; bit_n++)
if (entries_32 & (1 << bit_n)) if (entries_32 & (1u << bit_n))
out->push_back((int)((it - it_begin) << 5) + bit_n); out->push_back((int)((it - it_begin) << 5) + bit_n);
} }
@ -1829,15 +1893,14 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
{ {
ImFontBuildSrcData& src_tmp = src_tmp_array[src_i]; ImFontBuildSrcData& src_tmp = src_tmp_array[src_i];
ImFontBuildDstData& dst_tmp = dst_tmp_array[src_tmp.DstIndex]; ImFontBuildDstData& dst_tmp = dst_tmp_array[src_tmp.DstIndex];
ImFontConfig& cfg = atlas->ConfigData[src_i];
src_tmp.GlyphsSet.Resize(src_tmp.GlyphsHighest + 1); src_tmp.GlyphsSet.Resize(src_tmp.GlyphsHighest + 1);
if (dst_tmp.SrcCount > 1 && dst_tmp.GlyphsSet.Storage.empty()) if (dst_tmp.GlyphsSet.Storage.empty())
dst_tmp.GlyphsSet.Resize(dst_tmp.GlyphsHighest + 1); dst_tmp.GlyphsSet.Resize(dst_tmp.GlyphsHighest + 1);
for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2) for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
for (int codepoint = src_range[0]; codepoint <= src_range[1]; codepoint++) for (int codepoint = src_range[0]; codepoint <= src_range[1]; codepoint++)
{ {
if (cfg.MergeMode && dst_tmp.GlyphsSet.GetBit(codepoint)) // Don't overwrite existing glyphs. We could make this an option (e.g. MergeOverwrite) if (dst_tmp.GlyphsSet.GetBit(codepoint)) // Don't overwrite existing glyphs. We could make this an option for MergeMode (e.g. MergeOverwrite==true)
continue; continue;
if (!stbtt_FindGlyphIndex(&src_tmp.FontInfo, codepoint)) // It is actually in the font? if (!stbtt_FindGlyphIndex(&src_tmp.FontInfo, codepoint)) // It is actually in the font?
continue; continue;
@ -1846,7 +1909,6 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
src_tmp.GlyphsCount++; src_tmp.GlyphsCount++;
dst_tmp.GlyphsCount++; dst_tmp.GlyphsCount++;
src_tmp.GlyphsSet.SetBit(codepoint, true); src_tmp.GlyphsSet.SetBit(codepoint, true);
if (dst_tmp.SrcCount > 1)
dst_tmp.GlyphsSet.SetBit(codepoint, true); dst_tmp.GlyphsSet.SetBit(codepoint, true);
total_glyphs_count++; total_glyphs_count++;
} }
@ -1950,7 +2012,7 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
// 7. Allocate texture // 7. Allocate texture
atlas->TexHeight = (atlas->Flags & ImFontAtlasFlags_NoPowerOfTwoHeight) ? (atlas->TexHeight + 1) : ImUpperPowerOfTwo(atlas->TexHeight); atlas->TexHeight = (atlas->Flags & ImFontAtlasFlags_NoPowerOfTwoHeight) ? (atlas->TexHeight + 1) : ImUpperPowerOfTwo(atlas->TexHeight);
atlas->TexUvScale = ImVec2(1.0f / atlas->TexWidth, 1.0f / atlas->TexHeight); atlas->TexUvScale = ImVec2(1.0f / atlas->TexWidth, 1.0f / atlas->TexHeight);
atlas->TexPixelsAlpha8 = (unsigned char*)ImGui::MemAlloc(atlas->TexWidth * atlas->TexHeight); atlas->TexPixelsAlpha8 = (unsigned char*)IM_ALLOC(atlas->TexWidth * atlas->TexHeight);
memset(atlas->TexPixelsAlpha8, 0, atlas->TexWidth * atlas->TexHeight); memset(atlas->TexPixelsAlpha8, 0, atlas->TexWidth * atlas->TexHeight);
spc.pixels = atlas->TexPixelsAlpha8; spc.pixels = atlas->TexPixelsAlpha8;
spc.height = atlas->TexHeight; spc.height = atlas->TexHeight;
@ -2056,6 +2118,7 @@ void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* f
void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opaque) void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opaque)
{ {
stbrp_context* pack_context = (stbrp_context*)stbrp_context_opaque; stbrp_context* pack_context = (stbrp_context*)stbrp_context_opaque;
IM_ASSERT(pack_context != NULL);
ImVector<ImFontAtlas::CustomRect>& user_rects = atlas->CustomRects; ImVector<ImFontAtlas::CustomRect>& user_rects = atlas->CustomRects;
IM_ASSERT(user_rects.Size >= 1); // We expect at least the default custom rects to be registered, else something went wrong. IM_ASSERT(user_rects.Size >= 1); // We expect at least the default custom rects to be registered, else something went wrong.
@ -2162,7 +2225,8 @@ const ImWchar* ImFontAtlas::GetGlyphRangesChineseFull()
static const ImWchar ranges[] = static const ImWchar ranges[] =
{ {
0x0020, 0x00FF, // Basic Latin + Latin Supplement 0x0020, 0x00FF, // Basic Latin + Latin Supplement
0x3000, 0x30FF, // Punctuations, Hiragana, Katakana 0x2000, 0x206F, // General Punctuation
0x3000, 0x30FF, // CJK Symbols and Punctuations, Hiragana, Katakana
0x31F0, 0x31FF, // Katakana Phonetic Extensions 0x31F0, 0x31FF, // Katakana Phonetic Extensions
0xFF00, 0xFFEF, // Half-width characters 0xFF00, 0xFFEF, // Half-width characters
0x4e00, 0x9FAF, // CJK Ideograms 0x4e00, 0x9FAF, // CJK Ideograms
@ -2238,9 +2302,10 @@ const ImWchar* ImFontAtlas::GetGlyphRangesChineseSimplifiedCommon()
static ImWchar base_ranges[] = // not zero-terminated static ImWchar base_ranges[] = // not zero-terminated
{ {
0x0020, 0x00FF, // Basic Latin + Latin Supplement 0x0020, 0x00FF, // Basic Latin + Latin Supplement
0x3000, 0x30FF, // Punctuations, Hiragana, Katakana 0x2000, 0x206F, // General Punctuation
0x3000, 0x30FF, // CJK Symbols and Punctuations, Hiragana, Katakana
0x31F0, 0x31FF, // Katakana Phonetic Extensions 0x31F0, 0x31FF, // Katakana Phonetic Extensions
0xFF00, 0xFFEF, // Half-width characters 0xFF00, 0xFFEF // Half-width characters
}; };
static ImWchar full_ranges[IM_ARRAYSIZE(base_ranges) + IM_ARRAYSIZE(accumulative_offsets_from_0x4E00) * 2 + 1] = { 0 }; static ImWchar full_ranges[IM_ARRAYSIZE(base_ranges) + IM_ARRAYSIZE(accumulative_offsets_from_0x4E00) * 2 + 1] = { 0 };
if (!full_ranges[0]) if (!full_ranges[0])
@ -2296,9 +2361,9 @@ const ImWchar* ImFontAtlas::GetGlyphRangesJapanese()
static ImWchar base_ranges[] = // not zero-terminated static ImWchar base_ranges[] = // not zero-terminated
{ {
0x0020, 0x00FF, // Basic Latin + Latin Supplement 0x0020, 0x00FF, // Basic Latin + Latin Supplement
0x3000, 0x30FF, // Punctuations, Hiragana, Katakana 0x3000, 0x30FF, // CJK Symbols and Punctuations, Hiragana, Katakana
0x31F0, 0x31FF, // Katakana Phonetic Extensions 0x31F0, 0x31FF, // Katakana Phonetic Extensions
0xFF00, 0xFFEF, // Half-width characters 0xFF00, 0xFFEF // Half-width characters
}; };
static ImWchar full_ranges[IM_ARRAYSIZE(base_ranges) + IM_ARRAYSIZE(accumulative_offsets_from_0x4E00)*2 + 1] = { 0 }; static ImWchar full_ranges[IM_ARRAYSIZE(base_ranges) + IM_ARRAYSIZE(accumulative_offsets_from_0x4E00)*2 + 1] = { 0 };
if (!full_ranges[0]) if (!full_ranges[0])
@ -2334,6 +2399,23 @@ const ImWchar* ImFontAtlas::GetGlyphRangesThai()
return &ranges[0]; return &ranges[0];
} }
const ImWchar* ImFontAtlas::GetGlyphRangesVietnamese()
{
static const ImWchar ranges[] =
{
0x0020, 0x00FF, // Basic Latin
0x0102, 0x0103,
0x0110, 0x0111,
0x0128, 0x0129,
0x0168, 0x0169,
0x01A0, 0x01A1,
0x01AF, 0x01B0,
0x1EA0, 0x1EF9,
0,
};
return &ranges[0];
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] ImFontGlyphRangesBuilder // [SECTION] ImFontGlyphRangesBuilder
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -2361,11 +2443,12 @@ void ImFontGlyphRangesBuilder::AddRanges(const ImWchar* ranges)
void ImFontGlyphRangesBuilder::BuildRanges(ImVector<ImWchar>* out_ranges) void ImFontGlyphRangesBuilder::BuildRanges(ImVector<ImWchar>* out_ranges)
{ {
for (int n = 0; n < 0x10000; n++) int max_codepoint = 0x10000;
for (int n = 0; n < max_codepoint; n++)
if (GetBit(n)) if (GetBit(n))
{ {
out_ranges->push_back((ImWchar)n); out_ranges->push_back((ImWchar)n);
while (n < 0x10000 && GetBit(n + 1)) while (n < max_codepoint - 1 && GetBit(n + 1))
n++; n++;
out_ranges->push_back((ImWchar)n); out_ranges->push_back((ImWchar)n);
} }
@ -2378,38 +2461,36 @@ void ImFontGlyphRangesBuilder::BuildRanges(ImVector<ImWchar>* out_ranges)
ImFont::ImFont() ImFont::ImFont()
{ {
Scale = 1.0f; FontSize = 0.0f;
FallbackAdvanceX = 0.0f;
FallbackChar = (ImWchar)'?'; FallbackChar = (ImWchar)'?';
DisplayOffset = ImVec2(0.0f, 0.0f); DisplayOffset = ImVec2(0.0f, 0.0f);
ClearOutputData(); FallbackGlyph = NULL;
ContainerAtlas = NULL;
ConfigData = NULL;
ConfigDataCount = 0;
DirtyLookupTables = false;
Scale = 1.0f;
Ascent = Descent = 0.0f;
MetricsTotalSurface = 0;
} }
ImFont::~ImFont() ImFont::~ImFont()
{ {
// Invalidate active font so that the user gets a clear crash instead of a dangling pointer.
// If you want to delete fonts you need to do it between Render() and NewFrame().
// FIXME-CLEANUP
/*
ImGuiContext& g = *GImGui;
if (g.Font == this)
g.Font = NULL;
*/
ClearOutputData(); ClearOutputData();
} }
void ImFont::ClearOutputData() void ImFont::ClearOutputData()
{ {
FontSize = 0.0f; FontSize = 0.0f;
FallbackAdvanceX = 0.0f;
Glyphs.clear(); Glyphs.clear();
IndexAdvanceX.clear(); IndexAdvanceX.clear();
IndexLookup.clear(); IndexLookup.clear();
FallbackGlyph = NULL; FallbackGlyph = NULL;
FallbackAdvanceX = 0.0f;
ConfigDataCount = 0;
ConfigData = NULL;
ContainerAtlas = NULL; ContainerAtlas = NULL;
Ascent = Descent = 0.0f;
DirtyLookupTables = true; DirtyLookupTables = true;
Ascent = Descent = 0.0f;
MetricsTotalSurface = 0; MetricsTotalSurface = 0;
} }
@ -2440,7 +2521,7 @@ void ImFont::BuildLookupTable()
ImFontGlyph& tab_glyph = Glyphs.back(); ImFontGlyph& tab_glyph = Glyphs.back();
tab_glyph = *FindGlyph((ImWchar)' '); tab_glyph = *FindGlyph((ImWchar)' ');
tab_glyph.Codepoint = '\t'; tab_glyph.Codepoint = '\t';
tab_glyph.AdvanceX *= 4; tab_glyph.AdvanceX *= IM_TABSIZE;
IndexAdvanceX[(int)tab_glyph.Codepoint] = (float)tab_glyph.AdvanceX; IndexAdvanceX[(int)tab_glyph.Codepoint] = (float)tab_glyph.AdvanceX;
IndexLookup[(int)tab_glyph.Codepoint] = (ImWchar)(Glyphs.Size-1); IndexLookup[(int)tab_glyph.Codepoint] = (ImWchar)(Glyphs.Size-1);
} }
@ -2737,7 +2818,7 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 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 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); // ImGui functions generally already provides a valid text_end, so this is merely to handle direct calls. text_end = text_begin + strlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
// Align to be pixel perfect // Align to be pixel perfect
pos.x = (float)(int)pos.x + DisplayOffset.x; pos.x = (float)(int)pos.x + DisplayOffset.x;
@ -2920,7 +3001,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
draw_list->CmdBuffer[draw_list->CmdBuffer.Size-1].ElemCount -= (idx_expected_size - draw_list->IdxBuffer.Size); 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->_IdxWritePtr = idx_write; draw_list->_IdxWritePtr = idx_write;
draw_list->_VtxCurrentIdx = (unsigned int)draw_list->VtxBuffer.Size; draw_list->_VtxCurrentIdx = vtx_current_idx;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -2999,13 +3080,14 @@ void ImGui::RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, Im
const float inv_rounding = 1.0f / rounding; const float inv_rounding = 1.0f / rounding;
const float arc0_b = ImAcos01(1.0f - (p0.x - rect.Min.x) * inv_rounding); const float arc0_b = ImAcos01(1.0f - (p0.x - rect.Min.x) * inv_rounding);
const float arc0_e = ImAcos01(1.0f - (p1.x - rect.Min.x) * inv_rounding); const float arc0_e = ImAcos01(1.0f - (p1.x - rect.Min.x) * inv_rounding);
const float half_pi = IM_PI * 0.5f; // We will == compare to this because we know this is the exact value ImAcos01 can return.
const float x0 = ImMax(p0.x, rect.Min.x + rounding); const float x0 = ImMax(p0.x, rect.Min.x + rounding);
if (arc0_b == arc0_e) if (arc0_b == arc0_e)
{ {
draw_list->PathLineTo(ImVec2(x0, p1.y)); draw_list->PathLineTo(ImVec2(x0, p1.y));
draw_list->PathLineTo(ImVec2(x0, p0.y)); draw_list->PathLineTo(ImVec2(x0, p0.y));
} }
else if (arc0_b == 0.0f && arc0_e == IM_PI*0.5f) else if (arc0_b == 0.0f && arc0_e == half_pi)
{ {
draw_list->PathArcToFast(ImVec2(x0, p1.y - rounding), rounding, 3, 6); // BL draw_list->PathArcToFast(ImVec2(x0, p1.y - rounding), rounding, 3, 6); // BL
draw_list->PathArcToFast(ImVec2(x0, p0.y + rounding), rounding, 6, 9); // TR draw_list->PathArcToFast(ImVec2(x0, p0.y + rounding), rounding, 6, 9); // TR
@ -3025,7 +3107,7 @@ void ImGui::RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, Im
draw_list->PathLineTo(ImVec2(x1, p0.y)); draw_list->PathLineTo(ImVec2(x1, p0.y));
draw_list->PathLineTo(ImVec2(x1, p1.y)); draw_list->PathLineTo(ImVec2(x1, p1.y));
} }
else if (arc1_b == 0.0f && arc1_e == IM_PI*0.5f) else if (arc1_b == 0.0f && arc1_e == half_pi)
{ {
draw_list->PathArcToFast(ImVec2(x1, p0.y + rounding), rounding, 9, 12); // TR draw_list->PathArcToFast(ImVec2(x1, p0.y + rounding), rounding, 9, 12); // TR
draw_list->PathArcToFast(ImVec2(x1, p1.y - rounding), rounding, 0, 3); // BR draw_list->PathArcToFast(ImVec2(x1, p1.y - rounding), rounding, 0, 3); // BR
@ -3042,10 +3124,11 @@ void ImGui::RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, Im
// FIXME: Rendering an ellipsis "..." is a surprisingly tricky problem for us... we cannot rely on font glyph having it, // FIXME: Rendering an ellipsis "..." is a surprisingly tricky problem for us... we cannot rely on font glyph having it,
// and regular dot are typically too wide. If we render a dot/shape ourselves it comes with the risk that it wouldn't match // and regular dot are typically too wide. If we render a dot/shape ourselves it comes with the risk that it wouldn't match
// the boldness or positioning of what the font uses... // the boldness or positioning of what the font uses...
void ImGui::RenderPixelEllipsis(ImDrawList* draw_list, ImVec2 pos, int count, ImU32 col) void ImGui::RenderPixelEllipsis(ImDrawList* draw_list, ImVec2 pos, ImU32 col, int count)
{ {
ImFont* font = draw_list->_Data->Font; ImFont* font = draw_list->_Data->Font;
pos.y += (float)(int)(font->DisplayOffset.y + font->Ascent + 0.5f - 1.0f); const float font_scale = draw_list->_Data->FontSize / font->FontSize;
pos.y += (float)(int)(font->DisplayOffset.y + font->Ascent * font_scale + 0.5f - 1.0f);
for (int dot_n = 0; dot_n < count; dot_n++) for (int dot_n = 0; dot_n < count; dot_n++)
draw_list->AddRectFilled(ImVec2(pos.x + dot_n * 2.0f, pos.y), ImVec2(pos.x + dot_n * 2.0f + 1.0f, pos.y + 1.0f), col); draw_list->AddRectFilled(ImVec2(pos.x + dot_n * 2.0f, pos.y), ImVec2(pos.x + dot_n * 2.0f + 1.0f, pos.y + 1.0f), col);
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,10 @@
// stb_rect_pack.h - v0.11 - public domain - rectangle packing // [DEAR IMGUI]
// This is a slightly modified version of stb_rect_pack.h 0.99.
// Those changes would need to be pushed into nothings/stb:
// - Added STBRP__CDECL
// Grep for [DEAR IMGUI] to find the changes.
// stb_rect_pack.h - v0.99 - public domain - rectangle packing
// Sean Barrett 2014 // Sean Barrett 2014
// //
// Useful for e.g. packing rectangular textures into an atlas. // Useful for e.g. packing rectangular textures into an atlas.
@ -34,6 +40,7 @@
// //
// Version history: // Version history:
// //
// 0.99 (2019-02-07) warning fixes
// 0.11 (2017-03-03) return packing success/fail result // 0.11 (2017-03-03) return packing success/fail result
// 0.10 (2016-10-25) remove cast-away-const to avoid warnings // 0.10 (2016-10-25) remove cast-away-const to avoid warnings
// 0.09 (2016-08-27) fix compiler warnings // 0.09 (2016-08-27) fix compiler warnings
@ -204,6 +211,7 @@ struct stbrp_context
#define STBRP_ASSERT assert #define STBRP_ASSERT assert
#endif #endif
// [DEAR IMGUI] Added STBRP__CDECL
#ifdef _MSC_VER #ifdef _MSC_VER
#define STBRP__NOTUSED(v) (void)(v) #define STBRP__NOTUSED(v) (void)(v)
#define STBRP__CDECL __cdecl #define STBRP__CDECL __cdecl
@ -512,6 +520,7 @@ static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, i
return res; return res;
} }
// [DEAR IMGUI] Added STBRP__CDECL
static int STBRP__CDECL rect_height_compare(const void *a, const void *b) static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
{ {
const stbrp_rect *p = (const stbrp_rect *) a; const stbrp_rect *p = (const stbrp_rect *) a;
@ -523,6 +532,7 @@ static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
return (p->w > q->w) ? -1 : (p->w < q->w); return (p->w > q->w) ? -1 : (p->w < q->w);
} }
// [DEAR IMGUI] Added STBRP__CDECL
static int STBRP__CDECL rect_original_order(const void *a, const void *b) static int STBRP__CDECL rect_original_order(const void *a, const void *b)
{ {
const stbrp_rect *p = (const stbrp_rect *) a; const stbrp_rect *p = (const stbrp_rect *) a;
@ -543,9 +553,6 @@ STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int nu
// we use the 'was_packed' field internally to allow sorting/unsorting // we use the 'was_packed' field internally to allow sorting/unsorting
for (i=0; i < num_rects; ++i) { for (i=0; i < num_rects; ++i) {
rects[i].was_packed = i; rects[i].was_packed = i;
#ifndef STBRP_LARGE_RECTS
STBRP_ASSERT(rects[i].w <= 0xffff && rects[i].h <= 0xffff);
#endif
} }
// sort according to heuristic // sort according to heuristic

View File

@ -1,9 +1,10 @@
// [ImGui] this is a slightly modified version of stb_textedit.h 1.12. Those changes would need to be pushed into nothings/stb // [DEAR IMGUI]
// [ImGui] - 2018-06: fixed undo/redo after pasting large amount of text (over 32 kb). Redo will still fail when undo buffers are exhausted, but text won't be corrupted (see nothings/stb issue #620) // This is a slightly modified version of stb_textedit.h 1.13.
// [ImGui] - 2018-06: fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321) // Those changes would need to be pushed into nothings/stb:
// [ImGui] - fixed some minor warnings // - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321)
// Grep for [DEAR IMGUI] to find the changes.
// stb_textedit.h - v1.12 - public domain - Sean Barrett // stb_textedit.h - v1.13 - 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
@ -34,6 +35,7 @@
// //
// VERSION HISTORY // VERSION HISTORY
// //
// 1.13 (2019-02-07) fix bug in undo size management
// 1.12 (2018-01-29) user can change STB_TEXTEDIT_KEYTYPE, fix redo to avoid crash // 1.12 (2018-01-29) user can change STB_TEXTEDIT_KEYTYPE, fix redo to avoid crash
// 1.11 (2017-03-03) fix HOME on last line, dragging off single-line textfield // 1.11 (2017-03-03) fix HOME on last line, dragging off single-line textfield
// 1.10 (2016-10-25) supress warnings about casting away const with -Wcast-qual // 1.10 (2016-10-25) supress warnings about casting away const with -Wcast-qual
@ -563,7 +565,6 @@ static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *s
// now scan to find xpos // now scan to find xpos
find->x = r.x0; find->x = r.x0;
i = 0;
for (i=0; first+i < n; ++i) for (i=0; first+i < n; ++i)
find->x += STB_TEXTEDIT_GETWIDTH(str, first, i); find->x += STB_TEXTEDIT_GETWIDTH(str, first, i);
} }
@ -693,7 +694,7 @@ static void stb_textedit_prep_selection_at_cursor(STB_TexteditState *state)
static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
{ {
if (STB_TEXT_HAS_SELECTION(state)) { if (STB_TEXT_HAS_SELECTION(state)) {
stb_textedit_delete_selection(str,state); // implicity clamps stb_textedit_delete_selection(str,state); // implicitly clamps
state->has_preferred_x = 0; state->has_preferred_x = 0;
return 1; return 1;
} }
@ -745,7 +746,7 @@ retry:
state->has_preferred_x = 0; state->has_preferred_x = 0;
} }
} else { } else {
stb_textedit_delete_selection(str,state); // implicity clamps stb_textedit_delete_selection(str,state); // implicitly clamps
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) { if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) {
stb_text_makeundo_insert(state, state->cursor, 1); stb_text_makeundo_insert(state, state->cursor, 1);
++state->cursor; ++state->cursor;
@ -1133,7 +1134,14 @@ static void stb_textedit_discard_redo(StbUndoState *state)
state->undo_rec[i].char_storage += n; state->undo_rec[i].char_storage += n;
} }
// now move all the redo records towards the end of the buffer; the first one is at 'redo_point' // now move all the redo records towards the end of the buffer; the first one is at 'redo_point'
STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point+1, state->undo_rec + state->redo_point, (size_t) ((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0]))); // {DEAR IMGUI]
size_t move_size = (size_t)((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point - 1) * sizeof(state->undo_rec[0]));
const char* buf_begin = (char*)state->undo_rec; (void)buf_begin;
const char* buf_end = (char*)state->undo_rec + sizeof(state->undo_rec); (void)buf_end;
IM_ASSERT(((char*)(state->undo_rec + state->redo_point)) >= buf_begin);
IM_ASSERT(((char*)(state->undo_rec + state->redo_point + 1) + move_size) <= buf_end);
STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point+1, state->undo_rec + state->redo_point, move_size);
// now move redo_point to point to the new one // now move redo_point to point to the new one
++state->redo_point; ++state->redo_point;
} }

View File

@ -1,4 +1,9 @@
// stb_truetype.h - v1.19 - public domain // [DEAR IMGUI]
// This is a slightly modified version of stb_truetype.h 1.20.
// Mostly fixing for compiler and static analyzer warnings.
// Grep for [DEAR IMGUI] to find the changes.
// stb_truetype.h - v1.20 - public domain
// authored from 2009-2016 by Sean Barrett / RAD Game Tools // authored from 2009-2016 by Sean Barrett / RAD Game Tools
// //
// This library processes TrueType files: // This library processes TrueType files:
@ -49,6 +54,7 @@
// //
// VERSION HISTORY // VERSION HISTORY
// //
// 1.20 (2019-02-07) PackFontRange skips missing codepoints; GetScaleFontVMetrics()
// 1.19 (2018-02-11) GPOS kerning, STBTT_fmod // 1.19 (2018-02-11) GPOS kerning, STBTT_fmod
// 1.18 (2018-01-29) add missing function // 1.18 (2018-01-29) add missing function
// 1.17 (2017-07-23) make more arguments const; doc fix // 1.17 (2017-07-23) make more arguments const; doc fix
@ -75,7 +81,7 @@
// //
// USAGE // USAGE
// //
// Include this file in whatever places neeed to refer to it. In ONE C/C++ // Include this file in whatever places need to refer to it. In ONE C/C++
// file, write: // file, write:
// #define STB_TRUETYPE_IMPLEMENTATION // #define STB_TRUETYPE_IMPLEMENTATION
// before the #include of this file. This expands out the actual // before the #include of this file. This expands out the actual
@ -248,7 +254,7 @@
// Sample code 140 LOC / // Sample code 140 LOC /
// Truetype parsing 620 LOC ---- 620 LOC TrueType // Truetype parsing 620 LOC ---- 620 LOC TrueType
// Software rasterization 240 LOC \. // Software rasterization 240 LOC \.
// Curve tesselation 120 LOC \__ 550 LOC Bitmap creation // Curve tessellation 120 LOC \__ 550 LOC Bitmap creation
// Bitmap management 100 LOC / // Bitmap management 100 LOC /
// Baked bitmap interface 70 LOC / // Baked bitmap interface 70 LOC /
// Font name matching & access 150 LOC ---- 150 // Font name matching & access 150 LOC ---- 150
@ -556,6 +562,8 @@ STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int p
// //
// It's inefficient; you might want to c&p it and optimize it. // It's inefficient; you might want to c&p it and optimize it.
STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent, float *descent, float *lineGap);
// Query the font vertical metrics without having to create a font first.
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -641,6 +649,12 @@ STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h
// To use with PackFontRangesGather etc., you must set it before calls // To use with PackFontRangesGather etc., you must set it before calls
// call to PackFontRangesGatherRects. // call to PackFontRangesGatherRects.
STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip);
// If skip != 0, this tells stb_truetype to skip any codepoints for which
// there is no corresponding glyph. If skip=0, which is the default, then
// codepoints without a glyph recived the font's "missing character" glyph,
// typically an empty box by convention.
STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, // same data as above STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, // same data as above
int char_index, // character to display int char_index, // character to display
float *xpos, float *ypos, // pointers to current position in screen pixel space float *xpos, float *ypos, // pointers to current position in screen pixel space
@ -669,6 +683,7 @@ struct stbtt_pack_context {
int height; int height;
int stride_in_bytes; int stride_in_bytes;
int padding; int padding;
int skip_missing;
unsigned int h_oversample, v_oversample; unsigned int h_oversample, v_oversample;
unsigned char *pixels; unsigned char *pixels;
void *nodes; void *nodes;
@ -694,7 +709,7 @@ STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index);
// file will only define one font and it always be at offset 0, so it will // file will only define one font and it always be at offset 0, so it will
// return '0' for index 0, and -1 for all other indices. // return '0' for index 0, and -1 for all other indices.
// The following structure is defined publically so you can declare one on // The following structure is defined publicly 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.
struct stbtt_fontinfo struct stbtt_fontinfo
{ {
@ -733,6 +748,7 @@ STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codep
// and you want a speed-up, call this function with the character you're // and you want a speed-up, call this function with the character you're
// going to process, then use glyph-based functions instead of the // going to process, then use glyph-based functions instead of the
// codepoint-based functions. // codepoint-based functions.
// Returns 0 if the character codepoint is not defined in the font.
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -820,7 +836,7 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s
// returns # of vertices and fills *vertices with the pointer to them // returns # of vertices and fills *vertices with the pointer to them
// these are expressed in "unscaled" coordinates // these are expressed in "unscaled" coordinates
// //
// The shape is a series of countours. Each one starts with // The shape is a series of contours. Each one starts with
// a STBTT_moveto, then consists of a series of mixed // a STBTT_moveto, then consists of a series of mixed
// STBTT_lineto and STBTT_curveto segments. A lineto // STBTT_lineto and STBTT_curveto segments. A lineto
// draws a line from previous endpoint to its x,y; a curveto // draws a line from previous endpoint to its x,y; a curveto
@ -916,7 +932,7 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc
STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff); STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff);
// These functions compute a discretized SDF field for a single character, suitable for storing // These functions compute a discretized SDF field for a single character, suitable for storing
// in a single-channel texture, sampling with bilinear filtering, and testing against // in a single-channel texture, sampling with bilinear filtering, and testing against
// larger than some threshhold to produce scalable fonts. // larger than some threshold to produce scalable fonts.
// info -- the font // info -- the font
// scale -- controls the size of the resulting SDF bitmap, same as it would be creating a regular bitmap // scale -- controls the size of the resulting SDF bitmap, same as it would be creating a regular bitmap
// glyph/codepoint -- the character to generate the SDF for // glyph/codepoint -- the character to generate the SDF for
@ -1825,7 +1841,7 @@ static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, s
if (comp_verts) STBTT_free(comp_verts, info->userdata); if (comp_verts) STBTT_free(comp_verts, info->userdata);
return 0; return 0;
} }
if (num_vertices > 0) STBTT_memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex)); if (num_vertices > 0) STBTT_memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex)); //-V595
STBTT_memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex)); STBTT_memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex));
if (vertices) STBTT_free(vertices, info->userdata); if (vertices) STBTT_free(vertices, info->userdata);
vertices = tmp; vertices = tmp;
@ -2196,7 +2212,7 @@ static int stbtt__run_charstring(const stbtt_fontinfo *info, int glyph_index, st
} break; } break;
default: default:
if (b0 != 255 && b0 != 28 && (b0 < 32 || b0 > 254)) if (b0 != 255 && b0 != 28 && (b0 < 32 || b0 > 254)) //-V560
return STBTT__CSERR("reserved operator"); return STBTT__CSERR("reserved operator");
// push immediate // push immediate
@ -2368,7 +2384,8 @@ static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int glyph)
if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount) if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount)
return (stbtt_int32)ttUSHORT(classDef1ValueArray + 2 * (glyph - startGlyphID)); return (stbtt_int32)ttUSHORT(classDef1ValueArray + 2 * (glyph - startGlyphID));
classDefTable = classDef1ValueArray + 2 * glyphCount; // [DEAR IMGUI] Commented to fix static analyzer warning
//classDefTable = classDef1ValueArray + 2 * glyphCount;
} break; } break;
case 2: { case 2: {
@ -2392,7 +2409,8 @@ static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int glyph)
return (stbtt_int32)ttUSHORT(classRangeRecord + 4); return (stbtt_int32)ttUSHORT(classRangeRecord + 4);
} }
classDefTable = classRangeRecords + 6 * classRangeCount; // [DEAR IMGUI] Commented to fix static analyzer warning
//classDefTable = classRangeRecords + 6 * classRangeCount;
} break; } break;
default: { default: {
@ -3024,6 +3042,8 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
dx = -dx; dx = -dx;
dy = -dy; dy = -dy;
t = x0, x0 = xb, xb = t; t = x0, x0 = xb, xb = t;
// [DEAR IMGUI] Fix static analyzer warning
(void)dx; // [ImGui: fix static analyzer warning]
} }
x1 = (int) x_top; x1 = (int) x_top;
@ -3161,7 +3181,13 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
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) { if (z != NULL) {
STBTT_assert(z->ey >= scan_y_top); if (j == 0 && off_y != 0) {
if (z->ey < scan_y_top) {
// this can happen due to subpixel positioning and some kind of fp rounding error i think
z->ey = scan_y_top;
}
}
STBTT_assert(z->ey >= scan_y_top); // if we get really unlucky a tiny bit of an edge can be out of bounds
// insert at front // insert at front
z->next = active; z->next = active;
active = z; active = z;
@ -3230,7 +3256,7 @@ static void stbtt__sort_edges_ins_sort(stbtt__edge *p, int n)
static void stbtt__sort_edges_quicksort(stbtt__edge *p, int n) static void stbtt__sort_edges_quicksort(stbtt__edge *p, int n)
{ {
/* threshhold for transitioning to insertion sort */ /* threshold for transitioning to insertion sort */
while (n > 12) { while (n > 12) {
stbtt__edge t; stbtt__edge t;
int c01,c12,c,m,i,j; int c01,c12,c,m,i,j;
@ -3365,7 +3391,7 @@ static void stbtt__add_point(stbtt__point *points, int n, float x, float y)
points[n].y = y; points[n].y = y;
} }
// tesselate until threshhold p is happy... @TODO warped to compensate for non-linear stretching // tessellate until threshold p is happy... @TODO warped to compensate for non-linear stretching
static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float objspace_flatness_squared, int n) static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float objspace_flatness_squared, int n)
{ {
// midpoint // midpoint
@ -3790,6 +3816,7 @@ STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, in
spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw; spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw;
spc->h_oversample = 1; spc->h_oversample = 1;
spc->v_oversample = 1; spc->v_oversample = 1;
spc->skip_missing = 0;
stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes); stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes);
@ -3815,6 +3842,11 @@ STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h
spc->v_oversample = v_oversample; spc->v_oversample = v_oversample;
} }
STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip)
{
spc->skip_missing = skip;
}
#define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1) #define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1)
static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width) static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width)
@ -3968,6 +4000,9 @@ STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stb
int x0,y0,x1,y1; int x0,y0,x1,y1;
int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j]; int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
int glyph = stbtt_FindGlyphIndex(info, codepoint); int glyph = stbtt_FindGlyphIndex(info, codepoint);
if (glyph == 0 && spc->skip_missing) {
rects[k].w = rects[k].h = 0;
} else {
stbtt_GetGlyphBitmapBoxSubpixel(info,glyph, stbtt_GetGlyphBitmapBoxSubpixel(info,glyph,
scale * spc->h_oversample, scale * spc->h_oversample,
scale * spc->v_oversample, scale * spc->v_oversample,
@ -3975,6 +4010,7 @@ STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stb
&x0,&y0,&x1,&y1); &x0,&y0,&x1,&y1);
rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1); rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1);
rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1); rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1);
}
++k; ++k;
} }
} }
@ -4027,7 +4063,7 @@ STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const
sub_y = stbtt__oversample_shift(spc->v_oversample); sub_y = stbtt__oversample_shift(spc->v_oversample);
for (j=0; j < ranges[i].num_chars; ++j) { for (j=0; j < ranges[i].num_chars; ++j) {
stbrp_rect *r = &rects[k]; stbrp_rect *r = &rects[k];
if (r->was_packed) { if (r->was_packed && r->w != 0 && r->h != 0) {
stbtt_packedchar *bc = &ranges[i].chardata_for_range[j]; stbtt_packedchar *bc = &ranges[i].chardata_for_range[j];
int advance, lsb, x0,y0,x1,y1; int advance, lsb, x0,y0,x1,y1;
int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j]; int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
@ -4141,6 +4177,19 @@ STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *
return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1); return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1);
} }
STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent, float *descent, float *lineGap)
{
int i_ascent, i_descent, i_lineGap;
float scale;
stbtt_fontinfo info;
stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata, index));
scale = size > 0 ? stbtt_ScaleForPixelHeight(&info, size) : stbtt_ScaleForMappingEmToPixels(&info, -size);
stbtt_GetFontVMetrics(&info, &i_ascent, &i_descent, &i_lineGap);
*ascent = (float) i_ascent * scale;
*descent = (float) i_descent * scale;
*lineGap = (float) i_lineGap * scale;
}
STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer) STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer)
{ {
float ipw = 1.0f / pw, iph = 1.0f / ph; float ipw = 1.0f / pw, iph = 1.0f / ph;
@ -4253,7 +4302,7 @@ static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex
int winding = 0; int winding = 0;
orig[0] = x; orig[0] = x;
orig[1] = y; //orig[1] = y; // [DEAR IMGUI] commmented double assignment
// make sure y never passes through a vertex of the shape // make sure y never passes through a vertex of the shape
y_frac = (float) STBTT_fmod(y, 1.0f); y_frac = (float) STBTT_fmod(y, 1.0f);

View File

@ -5,6 +5,6 @@ imgui_stdlib.h + imgui_stdlib.cpp
imgui_scoped.h imgui_scoped.h
[Experimental, not currently in main repository] [Experimental, not currently in main repository]
Additional header file with some RAII-style wrappers for common ImGui functions. Additional header file with some RAII-style wrappers for common Dear ImGui functions.
Try by merging: https://github.com/ocornut/imgui/pull/2197 Try by merging: https://github.com/ocornut/imgui/pull/2197
Discuss at: https://github.com/ocornut/imgui/issues/2096 Discuss at: https://github.com/ocornut/imgui/issues/2096

View File

@ -63,3 +63,15 @@ bool ImGui::InputTextMultiline(const char* label, std::string* str, const ImVec2
cb_user_data.ChainCallbackUserData = user_data; cb_user_data.ChainCallbackUserData = user_data;
return InputTextMultiline(label, (char*)str->c_str(), str->capacity() + 1, size, flags, InputTextCallback, &cb_user_data); return InputTextMultiline(label, (char*)str->c_str(), str->capacity() + 1, size, flags, InputTextCallback, &cb_user_data);
} }
bool ImGui::InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
{
IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0);
flags |= ImGuiInputTextFlags_CallbackResize;
InputTextCallback_UserData cb_user_data;
cb_user_data.Str = str;
cb_user_data.ChainCallback = callback;
cb_user_data.ChainCallbackUserData = user_data;
return InputTextWithHint(label, hint, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, &cb_user_data);
}

View File

@ -19,4 +19,5 @@ namespace ImGui
// Because text input needs dynamic resizing, we need to setup a callback to grow the capacity // Because text input needs dynamic resizing, we need to setup a callback to grow the capacity
IMGUI_API bool InputText(const char* label, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); IMGUI_API bool InputText(const char* label, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
IMGUI_API bool InputTextMultiline(const char* label, std::string* str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); IMGUI_API bool InputTextMultiline(const char* label, std::string* str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
IMGUI_API bool InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
} }

View File

@ -1,3 +1,7 @@
dear imgui, v1.71
(Font Readme)
---------------------------------------
The code in imgui.cpp embeds a copy of 'ProggyClean.ttf' (by Tristan Grimmer), The code in imgui.cpp embeds a copy of 'ProggyClean.ttf' (by Tristan Grimmer),
a 13 pixels high, pixel-perfect font used by default. a 13 pixels high, pixel-perfect font used by default.
@ -5,7 +9,6 @@ We embed it font in source code so you can use Dear ImGui without any file syste
You may also load external .TTF/.OTF files. You may also load external .TTF/.OTF files.
The files in this folder are suggested fonts, provided as a convenience. The files in this folder are suggested fonts, provided as a convenience.
(Note: .OTF support in imstb_truetype.h currently doesn't appear to load every font)
Fonts are rasterized in a single texture at the time of calling either of io.Fonts->GetTexDataAsAlpha8()/GetTexDataAsRGBA32()/Build(). Fonts are rasterized in a single texture at the time of calling either of io.Fonts->GetTexDataAsAlpha8()/GetTexDataAsRGBA32()/Build().
Also read dear imgui FAQ in imgui.cpp! Also read dear imgui FAQ in imgui.cpp!
@ -23,16 +26,18 @@ If you have other loading/merging/adding fonts, you can post on the Dear ImGui "
- Fonts Loading Instructions - Fonts Loading Instructions
- FreeType rasterizer, Small font sizes - FreeType rasterizer, Small font sizes
- Building Custom Glyph Ranges - Building Custom Glyph Ranges
- Using custom colorful icons
- Embedding Fonts in Source Code - Embedding Fonts in Source Code
- Credits/Licences for fonts included in this folder - Credits/Licences for fonts included in this folder
- Links, Other fonts - Fonts Links
--------------------------------------- ---------------------------------------
README FIRST / FAQ README FIRST / FAQ
--------------------------------------- ---------------------------------------
- You can use the style editor ImGui::ShowStyleEditor() to browse your fonts and understand what's going on if you have an issue. - You can use the style editor ImGui::ShowStyleEditor() in the "Fonts" section to browse your fonts
and understand what's going on if you have an issue.
- Make sure your font ranges data are persistent (available during the call to GetTexDataAsAlpha8()/GetTexDataAsRGBA32()/Build(). - Make sure your font ranges data are persistent (available during the call to GetTexDataAsAlpha8()/GetTexDataAsRGBA32()/Build().
- Use C++11 u8"my text" syntax to encode literal strings as UTF-8. e.g.: - Use C++11 u8"my text" syntax to encode literal strings as UTF-8. e.g.:
u8"hello" u8"hello"
@ -106,11 +111,14 @@ Load .TTF/.OTF file with:
For advanced options create a ImFontConfig structure and pass it to the AddFont function (it will be copied internally): For advanced options create a ImFontConfig structure and pass it to the AddFont function (it will be copied internally):
ImFontConfig config; ImFontConfig config;
config.OversampleH = 3; config.OversampleH = 2;
config.OversampleV = 1; config.OversampleV = 1;
config.GlyphExtraSpacing.x = 1.0f; config.GlyphExtraSpacing.x = 1.0f;
ImFont* font = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, &config); ImFont* font = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, &config);
Read about oversampling here:
https://github.com/nothings/stb/blob/master/tests/oversample
If you have very large number of glyphs or multiple fonts, the texture may become too big for your graphics API. If you have very large number of glyphs or multiple fonts, the texture may become too big for your graphics API.
The typical result of failing to upload a texture is if every glyphs appears as white rectangles. The typical result of failing to upload a texture is if every glyphs appears as white rectangles.
In particular, using a large range such as GetGlyphRangesChineseSimplifiedCommon() is not recommended unless you In particular, using a large range such as GetGlyphRangesChineseSimplifiedCommon() is not recommended unless you
@ -191,6 +199,43 @@ For example: for a game where your script is known, if you can feed your entire
io.Fonts->Build(); // Build the atlas while 'ranges' is still in scope and not deleted. io.Fonts->Build(); // Build the atlas while 'ranges' is still in scope and not deleted.
---------------------------------------
USING CUSTOM COLORFUL ICONS
---------------------------------------
(This is a BETA api, use if you are familiar with dear imgui and with your rendering back-end)
You can use the ImFontAtlas::AddCustomRect() and ImFontAtlas::AddCustomRectFontGlyph() api to register rectangles
that will be packed into the font atlas texture. Register them before building the atlas, then call Build().
You can then use ImFontAtlas::GetCustomRectByIndex(int) to query the position/size of your rectangle within the
texture, and blit/copy any graphics data of your choice into those rectangles.
Pseudo-code:
// Add font, then register one custom 13x13 rectangle mapped to glyph 'a' of this font
ImFont* font = io.Fonts->AddFontDefault();
int rect_id = io.Fonts->AddCustomRectFontGlyph(font, 'a', 13, 13, 13+1);
// Build atlas
io.Fonts->Build();
// Retrieve texture in RGBA format
unsigned char* tex_pixels = NULL;
int tex_width, tex_height;
io.Fonts->GetTexDataAsRGBA32(&tex_pixels, &tex_width, &tex_height);
// Fill the custom rectangle with red pixels (in reality you would draw/copy your bitmap data here)
if (const ImFontAtlas::CustomRect* rect = io.Fonts->GetCustomRectByIndex(rect_id))
{
for (int y = 0; y < rect->Height; y++)
{
ImU32* p = (ImU32*)tex_pixels + (rect->Y + y) * tex_width + (rect->X);
for (int x = rect->Width; x > 0; x--)
*p++ = IM_COL32(255, 0, 0, 255);
}
}
--------------------------------------- ---------------------------------------
EMBEDDING FONTS IN SOURCE CODE EMBEDDING FONTS IN SOURCE CODE
--------------------------------------- ---------------------------------------
@ -198,7 +243,8 @@ For example: for a game where your script is known, if you can feed your entire
Compile and use 'binary_to_compressed_c.cpp' to create a compressed C style array that you can embed in source code. Compile and use 'binary_to_compressed_c.cpp' to create a compressed C style array that you can embed in source code.
See the documentation in binary_to_compressed_c.cpp for instruction on how to use the tool. See the documentation in binary_to_compressed_c.cpp for instruction on how to use the tool.
You may find a precompiled version binary_to_compressed_c.exe for Windows instead of demo binaries package (see README). You may find a precompiled version binary_to_compressed_c.exe for Windows instead of demo binaries package (see README).
The tool optionally used Base85 encoding to reduce the size of _source code_ but the read-only arrays will be about 20% bigger. The tool can optionally output Base85 encoding to reduce the size of _source code_ but the read-only arrays in the
actual binary will be about 20% bigger.
Then load the font with: Then load the font with:
ImFont* font = io.Fonts->AddFontFromMemoryCompressedTTF(compressed_data, compressed_data_size, size_pixels, ...); ImFont* font = io.Fonts->AddFontFromMemoryCompressedTTF(compressed_data, compressed_data_size, size_pixels, ...);
@ -233,13 +279,13 @@ ProggyClean.ttf
Copyright (c) 2004, 2005 Tristan Grimmer Copyright (c) 2004, 2005 Tristan Grimmer
MIT License MIT License
recommended loading setting in ImGui: Size = 13.0, DisplayOffset.Y = +1 recommended loading setting: Size = 13.0, DisplayOffset.Y = +1
http://www.proggyfonts.net/ http://www.proggyfonts.net/
ProggyTiny.ttf ProggyTiny.ttf
Copyright (c) 2004, 2005 Tristan Grimmer Copyright (c) 2004, 2005 Tristan Grimmer
MIT License MIT License
recommended loading setting in ImGui: Size = 10.0, DisplayOffset.Y = +1 recommended loading setting: Size = 10.0, DisplayOffset.Y = +1
http://www.proggyfonts.net/ http://www.proggyfonts.net/
Karla-Regular.ttf Karla-Regular.ttf
@ -291,6 +337,9 @@ MONOSPACE FONTS
https://github.com/kmar/Sweet16Font https://github.com/kmar/Sweet16Font
Also include .inl file to use directly in dear imgui. Also include .inl file to use directly in dear imgui.
Google Noto Mono Fonts
https://www.google.com/get/noto/
Typefaces for source code beautification Typefaces for source code beautification
https://github.com/chrissimpkins/codeface https://github.com/chrissimpkins/codeface

View File

@ -1,6 +1,6 @@
# imgui_freetype # imgui_freetype
Build font atlases using FreeType instead of stb_truetype (the default imgui's font rasterizer). Build font atlases using FreeType instead of stb_truetype (which is the default font rasterizer in Dear ImGui).
<br>by @vuhdo, @mikesart, @ocornut. <br>by @vuhdo, @mikesart, @ocornut.
### Usage ### Usage
@ -22,7 +22,7 @@ io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
FreeType assumes blending in linear space rather than gamma space. FreeType assumes blending in linear space rather than gamma space.
See FreeType note for [FT_Render_Glyph](https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Render_Glyph). See FreeType note for [FT_Render_Glyph](https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Render_Glyph).
For correct results you need to be using sRGB and convert to linear space in the pixel shader output. For correct results you need to be using sRGB and convert to linear space in the pixel shader output.
The default imgui styles will be impacted by this change (alpha values will need tweaking). The default Dear ImGui styles will be impacted by this change (alpha values will need tweaking).
### Test code Usage ### Test code Usage
```cpp ```cpp
@ -43,7 +43,8 @@ while (true)
if (freetype_test.UpdateRebuild()) if (freetype_test.UpdateRebuild())
{ {
// REUPLOAD FONT TEXTURE TO GPU // REUPLOAD FONT TEXTURE TO GPU
// e.g ImGui_ImplOpenGL3_DestroyDeviceObjects() + ImGui_ImplOpenGL3_CreateDeviceObjects() ImGui_ImplXXX_DestroyDeviceObjects();
ImGui_ImplXXX_CreateDeviceObjects();
} }
ImGui::NewFrame(); ImGui::NewFrame();
freetype_test.ShowFreetypeOptionsWindow(); freetype_test.ShowFreetypeOptionsWindow();
@ -67,6 +68,7 @@ struct FreeTypeTest
FontBuildMode BuildMode; FontBuildMode BuildMode;
bool WantRebuild; bool WantRebuild;
float FontsMultiply; float FontsMultiply;
int FontsPadding;
unsigned int FontsFlags; unsigned int FontsFlags;
FreeTypeTest() FreeTypeTest()
@ -74,6 +76,7 @@ struct FreeTypeTest
BuildMode = FontBuildMode_FreeType; BuildMode = FontBuildMode_FreeType;
WantRebuild = true; WantRebuild = true;
FontsMultiply = 1.0f; FontsMultiply = 1.0f;
FontsPadding = 1;
FontsFlags = 0; FontsFlags = 0;
} }
@ -83,10 +86,12 @@ struct FreeTypeTest
if (!WantRebuild) if (!WantRebuild)
return false; return false;
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
for (int n = 0; n < io.Fonts->Fonts.Size; n++) io.Fonts->TexGlyphPadding = FontsPadding;
for (int n = 0; n < io.Fonts->ConfigData.Size; n++)
{ {
io.Fonts->Fonts[n]->ConfigData->RasterizerMultiply = FontsMultiply; ImFontConfig* font_config = (ImFontConfig*)&io.Fonts->ConfigData[n];
io.Fonts->Fonts[n]->ConfigData->RasterizerFlags = (BuildMode == FontBuildMode_FreeType) ? FontsFlags : 0x00; font_config->RasterizerMultiply = FontsMultiply;
font_config->RasterizerFlags = (BuildMode == FontBuildMode_FreeType) ? FontsFlags : 0x00;
} }
if (BuildMode == FontBuildMode_FreeType) if (BuildMode == FontBuildMode_FreeType)
ImGuiFreeType::BuildFontAtlas(io.Fonts, FontsFlags); ImGuiFreeType::BuildFontAtlas(io.Fonts, FontsFlags);
@ -105,6 +110,7 @@ struct FreeTypeTest
ImGui::SameLine(); ImGui::SameLine();
WantRebuild |= ImGui::RadioButton("Stb (Default)", (int*)&BuildMode, FontBuildMode_Stb); WantRebuild |= ImGui::RadioButton("Stb (Default)", (int*)&BuildMode, FontBuildMode_Stb);
WantRebuild |= ImGui::DragFloat("Multiply", &FontsMultiply, 0.001f, 0.0f, 2.0f); WantRebuild |= ImGui::DragFloat("Multiply", &FontsMultiply, 0.001f, 0.0f, 2.0f);
WantRebuild |= ImGui::DragInt("Padding", &FontsPadding, 0.1f, 0, 16);
if (BuildMode == FontBuildMode_FreeType) if (BuildMode == FontBuildMode_FreeType)
{ {
WantRebuild |= ImGui::CheckboxFlags("NoHinting", &FontsFlags, ImGuiFreeType::NoHinting); WantRebuild |= ImGui::CheckboxFlags("NoHinting", &FontsFlags, ImGuiFreeType::NoHinting);
@ -114,6 +120,7 @@ struct FreeTypeTest
WantRebuild |= ImGui::CheckboxFlags("MonoHinting", &FontsFlags, ImGuiFreeType::MonoHinting); WantRebuild |= ImGui::CheckboxFlags("MonoHinting", &FontsFlags, ImGuiFreeType::MonoHinting);
WantRebuild |= ImGui::CheckboxFlags("Bold", &FontsFlags, ImGuiFreeType::Bold); WantRebuild |= ImGui::CheckboxFlags("Bold", &FontsFlags, ImGuiFreeType::Bold);
WantRebuild |= ImGui::CheckboxFlags("Oblique", &FontsFlags, ImGuiFreeType::Oblique); WantRebuild |= ImGui::CheckboxFlags("Oblique", &FontsFlags, ImGuiFreeType::Oblique);
WantRebuild |= ImGui::CheckboxFlags("Monochrome", &FontsFlags, ImGuiFreeType::Monochrome);
} }
ImGui::End(); ImGui::End();
} }
@ -121,6 +128,5 @@ struct FreeTypeTest
``` ```
### Known issues ### Known issues
- FreeType's memory allocator is not overridden.
- `cfg.OversampleH`, `OversampleV` are ignored (but perhaps not so necessary with this rasterizer). - `cfg.OversampleH`, `OversampleV` are ignored (but perhaps not so necessary with this rasterizer).

View File

@ -5,12 +5,14 @@
// Changelog: // Changelog:
// - v0.50: (2017/08/16) imported from https://github.com/Vuhdo/imgui_freetype into http://www.github.com/ocornut/imgui_club, updated for latest changes in ImFontAtlas, minor tweaks. // - v0.50: (2017/08/16) imported from https://github.com/Vuhdo/imgui_freetype into http://www.github.com/ocornut/imgui_club, updated for latest changes in ImFontAtlas, minor tweaks.
// - v0.51: (2017/08/26) cleanup, optimizations, support for ImFontConfig::RasterizerFlags, ImFontConfig::RasterizerMultiply. // - v0.51: (2017/08/26) cleanup, optimizations, support for ImFontConfig::RasterizerFlags, ImFontConfig::RasterizerMultiply.
// - v0.52: (2017/09/26) fixes for imgui internal changes // - v0.52: (2017/09/26) fixes for imgui internal changes.
// - v0.53: (2017/10/22) minor inconsequential change to match change in master (removed an unnecessary statement) // - v0.53: (2017/10/22) minor inconsequential change to match change in master (removed an unnecessary statement).
// - v0.54: (2018/01/22) fix for addition of ImFontAtlas::TexUvscale member // - v0.54: (2018/01/22) fix for addition of ImFontAtlas::TexUvscale member.
// - v0.55: (2018/02/04) moved to main imgui repository (away from http://www.github.com/ocornut/imgui_club) // - v0.55: (2018/02/04) moved to main imgui repository (away from http://www.github.com/ocornut/imgui_club)
// - v0.56: (2018/06/08) added support for ImFontConfig::GlyphMinAdvanceX, GlyphMaxAdvanceX // - v0.56: (2018/06/08) added support for ImFontConfig::GlyphMinAdvanceX, GlyphMaxAdvanceX.
// - v0.60: (2019/01/10) re-factored to match big update in STB builder. fixed texture height waste. fixed redundant glyphs when merging. support for glyph padding. // - v0.60: (2019/01/10) re-factored to match big update in STB builder. fixed texture height waste. fixed redundant glyphs when merging. support for glyph padding.
// - v0.61: (2019/01/15) added support for imgui allocators + added FreeType only override function SetAllocatorFunctions().
// - v0.62: (2019/02/09) added RasterizerFlags::Monochrome flag to disable font anti-aliasing (combine with ::MonoHinting for best results!)
// Gamma Correct Blending: // Gamma Correct Blending:
// FreeType assumes blending in linear space rather than gamma space. // FreeType assumes blending in linear space rather than gamma space.
@ -18,7 +20,6 @@
// For correct results you need to be using sRGB and convert to linear space in the pixel shader output. // For correct results you need to be using sRGB and convert to linear space in the pixel shader output.
// The default imgui styles will be impacted by this change (alpha values will need tweaking). // The default imgui styles will be impacted by this change (alpha values will need tweaking).
// FIXME: FreeType's memory allocator is not overridden.
// FIXME: cfg.OversampleH, OversampleV are not supported (but perhaps not so necessary with this rasterizer). // FIXME: cfg.OversampleH, OversampleV are not supported (but perhaps not so necessary with this rasterizer).
#include "imgui_freetype.h" #include "imgui_freetype.h"
@ -26,6 +27,7 @@
#include <stdint.h> #include <stdint.h>
#include <ft2build.h> #include <ft2build.h>
#include FT_FREETYPE_H // <freetype/freetype.h> #include FT_FREETYPE_H // <freetype/freetype.h>
#include FT_MODULE_H // <freetype/ftmodapi.h>
#include FT_GLYPH_H // <freetype/ftglyph.h> #include FT_GLYPH_H // <freetype/ftglyph.h>
#include FT_SYNTHESIS_H // <freetype/ftsynth.h> #include FT_SYNTHESIS_H // <freetype/ftsynth.h>
@ -108,6 +110,7 @@ namespace
FT_Face Face; FT_Face Face;
unsigned int UserFlags; // = ImFontConfig::RasterizerFlags unsigned int UserFlags; // = ImFontConfig::RasterizerFlags
FT_Int32 LoadFlags; FT_Int32 LoadFlags;
FT_Render_Mode RenderMode;
}; };
// From SDL_ttf: Handy routines for converting from fixed point // From SDL_ttf: Handy routines for converting from fixed point
@ -115,7 +118,6 @@ namespace
bool FreeTypeFont::InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_user_flags) bool FreeTypeFont::InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_user_flags)
{ {
// FIXME: substitute allocator
FT_Error error = FT_New_Memory_Face(ft_library, (uint8_t*)cfg.FontData, (uint32_t)cfg.FontDataSize, (uint32_t)cfg.FontNo, &Face); FT_Error error = FT_New_Memory_Face(ft_library, (uint8_t*)cfg.FontData, (uint32_t)cfg.FontDataSize, (uint32_t)cfg.FontNo, &Face);
if (error != 0) if (error != 0)
return false; return false;
@ -142,6 +144,11 @@ namespace
else else
LoadFlags |= FT_LOAD_TARGET_NORMAL; LoadFlags |= FT_LOAD_TARGET_NORMAL;
if (UserFlags & ImGuiFreeType::Monochrome)
RenderMode = FT_RENDER_MODE_MONO;
else
RenderMode = FT_RENDER_MODE_NORMAL;
return true; return true;
} }
@ -208,7 +215,7 @@ namespace
const FT_Bitmap* FreeTypeFont::RenderGlyphAndGetInfo(GlyphInfo* out_glyph_info) const FT_Bitmap* FreeTypeFont::RenderGlyphAndGetInfo(GlyphInfo* out_glyph_info)
{ {
FT_GlyphSlot slot = Face->glyph; FT_GlyphSlot slot = Face->glyph;
FT_Error error = FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL); FT_Error error = FT_Render_Glyph(slot, RenderMode);
if (error != 0) if (error != 0)
return NULL; return NULL;
@ -230,6 +237,10 @@ namespace
const uint8_t* src = ft_bitmap->buffer; const uint8_t* src = ft_bitmap->buffer;
const uint32_t src_pitch = ft_bitmap->pitch; const uint32_t src_pitch = ft_bitmap->pitch;
switch (ft_bitmap->pixel_mode)
{
case FT_PIXEL_MODE_GRAY: // Grayscale image, 1 byte per pixel.
{
if (multiply_table == NULL) if (multiply_table == NULL)
{ {
for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch) for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
@ -241,13 +252,37 @@ namespace
for (uint32_t x = 0; x < w; x++) for (uint32_t x = 0; x < w; x++)
dst[x] = multiply_table[src[x]]; dst[x] = multiply_table[src[x]];
} }
break;
}
case FT_PIXEL_MODE_MONO: // Monochrome image, 1 bit per pixel. The bits in each byte are ordered from MSB to LSB.
{
uint8_t color0 = multiply_table ? multiply_table[0] : 0;
uint8_t color1 = multiply_table ? multiply_table[255] : 255;
for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
{
uint8_t bits = 0;
const uint8_t* bits_ptr = src;
for (uint32_t x = 0; x < w; x++, bits <<= 1)
{
if ((x & 7) == 0)
bits = *bits_ptr++;
dst[x] = (bits & 0x80) ? color1 : color0;
}
}
break;
}
default:
IM_ASSERT(0 && "FreeTypeFont::BlitGlyph(): Unknown bitmap pixel mode!");
}
} }
} }
#ifndef STB_RECT_PACK_IMPLEMENTATION // in case the user already have an implementation in the _same_ compilation unit (e.g. unity builds)
#define STBRP_ASSERT(x) IM_ASSERT(x) #define STBRP_ASSERT(x) IM_ASSERT(x)
#define STBRP_STATIC #define STBRP_STATIC
#define STB_RECT_PACK_IMPLEMENTATION #define STB_RECT_PACK_IMPLEMENTATION
#include "imstb_rectpack.h" #include "imstb_rectpack.h"
#endif
struct ImFontBuildSrcGlyphFT struct ImFontBuildSrcGlyphFT
{ {
@ -334,15 +369,14 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
{ {
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i]; ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
ImFontBuildDstDataFT& dst_tmp = dst_tmp_array[src_tmp.DstIndex]; ImFontBuildDstDataFT& dst_tmp = dst_tmp_array[src_tmp.DstIndex];
ImFontConfig& cfg = atlas->ConfigData[src_i];
src_tmp.GlyphsSet.Resize(src_tmp.GlyphsHighest + 1); src_tmp.GlyphsSet.Resize(src_tmp.GlyphsHighest + 1);
if (dst_tmp.SrcCount > 1 && dst_tmp.GlyphsSet.Storage.empty()) if (dst_tmp.GlyphsSet.Storage.empty())
dst_tmp.GlyphsSet.Resize(dst_tmp.GlyphsHighest + 1); dst_tmp.GlyphsSet.Resize(dst_tmp.GlyphsHighest + 1);
for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2) for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
for (int codepoint = src_range[0]; codepoint <= src_range[1]; codepoint++) for (int codepoint = src_range[0]; codepoint <= src_range[1]; codepoint++)
{ {
if (cfg.MergeMode && dst_tmp.GlyphsSet.GetBit(codepoint)) // Don't overwrite existing glyphs. We could make this an option (e.g. MergeOverwrite) if (dst_tmp.GlyphsSet.GetBit(codepoint)) // Don't overwrite existing glyphs. We could make this an option (e.g. MergeOverwrite)
continue; continue;
uint32_t glyph_index = FT_Get_Char_Index(src_tmp.Font.Face, codepoint); // It is actually in the font? (FIXME-OPT: We are not storing the glyph_index..) uint32_t glyph_index = FT_Get_Char_Index(src_tmp.Font.Face, codepoint); // It is actually in the font? (FIXME-OPT: We are not storing the glyph_index..)
if (glyph_index == 0) if (glyph_index == 0)
@ -352,7 +386,6 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
src_tmp.GlyphsCount++; src_tmp.GlyphsCount++;
dst_tmp.GlyphsCount++; dst_tmp.GlyphsCount++;
src_tmp.GlyphsSet.SetBit(codepoint, true); src_tmp.GlyphsSet.SetBit(codepoint, true);
if (dst_tmp.SrcCount > 1)
dst_tmp.GlyphsSet.SetBit(codepoint, true); dst_tmp.GlyphsSet.SetBit(codepoint, true);
total_glyphs_count++; total_glyphs_count++;
} }
@ -398,7 +431,7 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
const int BITMAP_BUFFERS_CHUNK_SIZE = 256 * 1024; const int BITMAP_BUFFERS_CHUNK_SIZE = 256 * 1024;
int buf_bitmap_current_used_bytes = 0; int buf_bitmap_current_used_bytes = 0;
ImVector<unsigned char*> buf_bitmap_buffers; ImVector<unsigned char*> buf_bitmap_buffers;
buf_bitmap_buffers.push_back((unsigned char*)ImGui::MemAlloc(BITMAP_BUFFERS_CHUNK_SIZE)); buf_bitmap_buffers.push_back((unsigned char*)IM_ALLOC(BITMAP_BUFFERS_CHUNK_SIZE));
// 4. Gather glyphs sizes so we can pack them in our virtual canvas. // 4. Gather glyphs sizes so we can pack them in our virtual canvas.
// 8. Render/rasterize font characters into the texture // 8. Render/rasterize font characters into the texture
@ -440,7 +473,7 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
if (buf_bitmap_current_used_bytes + bitmap_size_in_bytes > BITMAP_BUFFERS_CHUNK_SIZE) if (buf_bitmap_current_used_bytes + bitmap_size_in_bytes > BITMAP_BUFFERS_CHUNK_SIZE)
{ {
buf_bitmap_current_used_bytes = 0; buf_bitmap_current_used_bytes = 0;
buf_bitmap_buffers.push_back((unsigned char*)ImGui::MemAlloc(BITMAP_BUFFERS_CHUNK_SIZE)); buf_bitmap_buffers.push_back((unsigned char*)IM_ALLOC(BITMAP_BUFFERS_CHUNK_SIZE));
} }
// Blit rasterized pixels to our temporary buffer and keep a pointer to it. // Blit rasterized pixels to our temporary buffer and keep a pointer to it.
@ -493,7 +526,7 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
// 7. Allocate texture // 7. Allocate texture
atlas->TexHeight = (atlas->Flags & ImFontAtlasFlags_NoPowerOfTwoHeight) ? (atlas->TexHeight + 1) : ImUpperPowerOfTwo(atlas->TexHeight); atlas->TexHeight = (atlas->Flags & ImFontAtlasFlags_NoPowerOfTwoHeight) ? (atlas->TexHeight + 1) : ImUpperPowerOfTwo(atlas->TexHeight);
atlas->TexUvScale = ImVec2(1.0f / atlas->TexWidth, 1.0f / atlas->TexHeight); atlas->TexUvScale = ImVec2(1.0f / atlas->TexWidth, 1.0f / atlas->TexHeight);
atlas->TexPixelsAlpha8 = (unsigned char*)ImGui::MemAlloc(atlas->TexWidth * atlas->TexHeight); atlas->TexPixelsAlpha8 = (unsigned char*)IM_ALLOC(atlas->TexWidth * atlas->TexHeight);
memset(atlas->TexPixelsAlpha8, 0, atlas->TexWidth * atlas->TexHeight); memset(atlas->TexPixelsAlpha8, 0, atlas->TexWidth * atlas->TexHeight);
// 8. Copy rasterized font characters back into the main texture // 8. Copy rasterized font characters back into the main texture
@ -557,7 +590,7 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
// Cleanup // Cleanup
for (int buf_i = 0; buf_i < buf_bitmap_buffers.Size; buf_i++) for (int buf_i = 0; buf_i < buf_bitmap_buffers.Size; buf_i++)
ImGui::MemFree(buf_bitmap_buffers[buf_i]); IM_FREE(buf_bitmap_buffers[buf_i]);
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++) for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
src_tmp_array[src_i].~ImFontBuildSrcDataFT(); src_tmp_array[src_i].~ImFontBuildSrcDataFT();
@ -566,15 +599,75 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
return true; return true;
} }
// Default memory allocators
static void* ImFreeTypeDefaultAllocFunc(size_t size, void* user_data) { IM_UNUSED(user_data); return IM_ALLOC(size); }
static void ImFreeTypeDefaultFreeFunc(void* ptr, void* user_data) { IM_UNUSED(user_data); IM_FREE(ptr); }
// Current memory allocators
static void* (*GImFreeTypeAllocFunc)(size_t size, void* user_data) = ImFreeTypeDefaultAllocFunc;
static void (*GImFreeTypeFreeFunc)(void* ptr, void* user_data) = ImFreeTypeDefaultFreeFunc;
static void* GImFreeTypeAllocatorUserData = NULL;
// FreeType memory allocation callbacks
static void* FreeType_Alloc(FT_Memory /*memory*/, long size)
{
return GImFreeTypeAllocFunc((size_t)size, GImFreeTypeAllocatorUserData);
}
static void FreeType_Free(FT_Memory /*memory*/, void* block)
{
GImFreeTypeFreeFunc(block, GImFreeTypeAllocatorUserData);
}
static void* FreeType_Realloc(FT_Memory /*memory*/, long cur_size, long new_size, void* block)
{
// Implement realloc() as we don't ask user to provide it.
if (block == NULL)
return GImFreeTypeAllocFunc((size_t)new_size, GImFreeTypeAllocatorUserData);
if (new_size == 0)
{
GImFreeTypeFreeFunc(block, GImFreeTypeAllocatorUserData);
return NULL;
}
if (new_size > cur_size)
{
void* new_block = GImFreeTypeAllocFunc((size_t)new_size, GImFreeTypeAllocatorUserData);
memcpy(new_block, block, (size_t)cur_size);
GImFreeTypeFreeFunc(block, GImFreeTypeAllocatorUserData);
return new_block;
}
return block;
}
bool ImGuiFreeType::BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags) bool ImGuiFreeType::BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags)
{ {
// FreeType memory management: https://www.freetype.org/freetype2/docs/design/design-4.html
FT_MemoryRec_ memory_rec = { 0 };
memory_rec.alloc = &FreeType_Alloc;
memory_rec.free = &FreeType_Free;
memory_rec.realloc = &FreeType_Realloc;
// https://www.freetype.org/freetype2/docs/reference/ft2-module_management.html#FT_New_Library
FT_Library ft_library; FT_Library ft_library;
FT_Error error = FT_Init_FreeType(&ft_library); FT_Error error = FT_New_Library(&memory_rec, &ft_library);
if (error != 0) if (error != 0)
return false; return false;
// If you don't call FT_Add_Default_Modules() the rest of code may work, but FreeType won't use our custom allocator.
FT_Add_Default_Modules(ft_library);
bool ret = ImFontAtlasBuildWithFreeType(ft_library, atlas, extra_flags); bool ret = ImFontAtlasBuildWithFreeType(ft_library, atlas, extra_flags);
FT_Done_FreeType(ft_library); FT_Done_Library(ft_library);
return ret; return ret;
} }
void ImGuiFreeType::SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data)
{
GImFreeTypeAllocFunc = alloc_func;
GImFreeTypeFreeFunc = free_func;
GImFreeTypeAllocatorUserData = user_data;
}

Some files were not shown because too many files have changed in this diff Show More