Compare commits

..

187 Commits
v1.14 ... v1.20

Author SHA1 Message Date
b0ea57e518 Version number 2015-01-07 19:07:43 +00:00
4260195159 Revert "Reexported proggy_clean_13 in a 256x64 texture (instead of 256x128) and documented exact export parameters"
Correct but cause problems because many people don't have 1 BPP PNG loaders

This reverts commit 98a38e24ab.
2015-01-07 18:59:44 +00:00
26fdf1655c Fixed leak on shutdown (fixes #110) + possible uninitialized member. 2015-01-07 14:55:35 +00:00
c1251d2994 Examples: Fixed warnings for Clang 2015-01-06 17:43:23 +00:00
1c657564ac Examples: Added STB_IMAGE_STATIC in examples to avoid conflicting implementation. Relate to #109 2015-01-06 17:35:36 +00:00
98a38e24ab Reexported proggy_clean_13 in a 256x64 texture (instead of 256x128) and documented exact export parameters 2015-01-05 11:13:02 +00:00
0505995193 Very minor code/comments tweaks. 2015-01-04 22:29:53 +00:00
4905ec46f1 Fixed hovering of child windows / combo boxes that extend beyond the root window limits. 2015-01-04 22:07:37 +00:00
3fe669f547 Failure in LogToFile() treated at an error (assert) in the absence of another type of error handling. 2015-01-04 21:37:49 +00:00
22c1d7eded Renamed some color enums 2015-01-04 19:37:24 +00:00
39373b563b Checkbox and Radio buttons activate on click-release to be consistent with other widgets and most UI 2015-01-04 19:23:36 +00:00
97d34271f8 Fix clipboard pasting into an InputText box not filtering the characters according to input box semantic (number, etc.) 2015-01-04 18:47:08 +00:00
a5f4108781 Activating widget bring parent window to front 2015-01-04 18:36:33 +00:00
3674d30e90 Fixed clicking on Combo box label. 2015-01-04 18:32:15 +00:00
2268b098e0 Avoid marking settings as dirty when window is marked unsaved + minor FocusWindow() optimisation 2015-01-04 18:23:30 +00:00
4bccc06933 Dragging outside area of a widget while it is active doesn't trigger hover on other widgets. 2015-01-04 18:12:30 +00:00
ee49c2288d Todo items. 2015-01-03 17:38:10 +00:00
34664dc28c InputText() consume input characters immediately (fixes #105) 2015-01-03 17:37:39 +00:00
e4f96147de Update README.md 2014-12-31 15:55:34 +00:00
12225abfe2 Version number (fix) 2014-12-31 10:38:36 +00:00
505bd1a66d Fixed text input filtering for character in the 128-255 range. 2014-12-31 09:49:53 +00:00
c9002620c6 Update README.md 2014-12-30 17:13:04 +00:00
f8c58fe328 Fix for Clang 2014-12-30 16:55:32 +00:00
74ab555558 Examples: Console:: added support for History callbacks + cleanup to be self contained. 2014-12-30 16:49:39 +00:00
da5227fa28 Added comment about defining IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT in imconfig.h 2014-12-30 15:44:19 +00:00
3b028c7ebf Fixed InputInt() InputFloat() label not declaring their width, breaking SameLine (bug #100)
+ shallow cleanups
2014-12-30 15:38:28 +00:00
2d111ccb55 crc32 on strings is performed in one pass - removed the strlen() call. 2014-12-30 15:18:21 +00:00
691ca46978 Version number 2014-12-30 15:10:55 +00:00
209be54e49 Version number 2014-12-30 12:21:57 +00:00
aa750d538d Style editor: added an Output button to output colors to clipboard/tty 2014-12-30 12:08:33 +00:00
929f127d06 Added SliderInt2(), SliderInt3(), SliderInt4() for consistency 2014-12-30 11:54:04 +00:00
60b4389ac1 Empty label consistently remove the inner-padding normally preceeding the label. 2014-12-30 11:41:46 +00:00
a950df6655 Tightening default style (saving -2 pixels on each axis per widget) 2014-12-30 10:00:00 +00:00
409b1ac6b5 Log output \r\n under Windows so files are readable with Notepad 2014-12-29 20:41:27 +00:00
036a153cf4 Log depth padding relative to start depth. Tree node and headers looking better when logged to text. Added LogText(). 2014-12-29 20:18:52 +00:00
886d954e3d GetStyleColorName -> GetStyleColName for consistency with type name. Removed ImGuiStyleVar_ColumnsMinSpacing 2014-12-29 19:56:01 +00:00
39952d2362 Renamed GetTreeStateStorage() to GetStateStorage(). Columns storing floats instead of fixed point integers 2014-12-29 18:17:54 +00:00
1b25fa8169 Added LogFinish() to stop logging at an arbitrary point. 2014-12-29 18:13:41 +00:00
0796dc0dc1 Minor fix for cases of malformed .ini file (zero-terminating text file like it was before previous commit). 2014-12-29 18:05:22 +00:00
8994f2f1e4 Cleanup. Removed unnecessary calls to sqrtf(). Factoring bits into ImLoadFileToMemory(). Added index of static helpers. 2014-12-29 11:23:03 +00:00
e2fbbe0274 Factoring bits out of Begin() into a private CreateNewWindow() funciton
(Hopefully to ease a bit the merging work for ProDBG)
2014-12-28 17:54:02 +00:00
5b7ed5432e CalcTextSize() default third parameter to false because it almost never makes sense to use it from the outside (may obsolete it) 2014-12-28 16:17:08 +00:00
bf3212c681 Taking notes of issues/todo 2014-12-28 16:09:19 +00:00
34728394ec Fixed clipped ImGui::Combo not registering its size properly (was flickering when scrolling with combo on the edge of clipping region) 2014-12-26 12:38:13 +00:00
90351298d1 Renamed second parameter to Begin() to 'bool* p_opened' to be more self-explanatory. Added more comments on the use of Begin(). 2014-12-22 13:29:39 +00:00
69f3d67d18 Preserve windows position on zero-sized display (minimized). 2014-12-22 02:14:31 +00:00
d6c13128b9 Update README.md - tweaks 2014-12-22 02:07:02 +00:00
b3febabc30 OpenGL3 example: fix growing of VBO 2014-12-22 01:47:34 +00:00
ac29859f70 Support zero-sized display, now sets default as -1,-1 and assert if display size is negative. 2014-12-22 01:45:13 +00:00
a3af51fd4e Added ImGuiStyleVar_WindowRounding enum for PushStyleVar() API 2014-12-19 12:56:00 +00:00
b09c49180f Update README.md minor fixes 2014-12-14 10:44:43 +00:00
7e868e2842 Cleanup todo list, removed 3 done items + added 1 new 2014-12-11 10:12:52 +00:00
0056ccce26 Version number 2014-12-10 23:40:25 +00:00
486506e37f Update README.md 2014-12-10 23:39:48 +00:00
e9e0e36f98 New and better Set[Next]Window(Pos|Size|Collapsed) API.
Removed rarely useful SetNewWindowDefaultPos() in favor of new API.
2014-12-10 19:22:30 +00:00
3399890a84 Added ImGuiWindowFlags_NoSavedSettings flag + Fixed overlay example app. 2014-12-10 17:13:45 +00:00
2a3bff9a82 Comments 2014-12-10 16:56:11 +00:00
09bacfbe18 OpenGL example: allow resizing window. 2014-12-10 15:27:40 +00:00
cca5f473ca Clarified comment 2014-12-08 17:18:20 +00:00
6523fb263d OpenGL3 example: fixed mouse handling. 2014-12-08 17:15:08 +00:00
bdb2344db0 ImGuiStorage helper can store float + added functions to get pointer to data. Exposed ImGui::GetId() - may be misleading? 2014-12-08 17:14:54 +00:00
0a0769227d Added Travis CI build banner. 2014-12-07 10:17:39 +00:00
6252b26af2 Update README.md 2014-12-07 10:15:34 +00:00
987188d437 Fix Clang warning with offsetof() macro? Added -Wall in OpenGL 3 example. 2014-12-07 09:58:45 +00:00
71e20680db Setup Travis CI integration with Clang + -Wall in Makefiles 2014-12-07 09:48:01 +00:00
bb20065be0 Setup Travis CI integration
Getting there!
2014-12-06 23:30:38 +00:00
fec067d033 Setup Travis CI integration
More libs needed
2014-12-06 23:27:40 +00:00
2eb837ea86 Setup Travis CI integration
Different PPA source
2014-12-06 23:23:57 +00:00
857a4e364c Setup Travis CI integration
Yes please
2014-12-06 23:21:05 +00:00
2599849e9c Setup Travis CI integration
Trying again with a PPA for glfw3-dev
2014-12-06 23:17:30 +00:00
da1b8f7e46 Setup Travis CI integration
Argh.
2014-12-06 23:06:04 +00:00
0687af2ce5 Setup Travis CI integration
Failing to get glfw3 for ubuntu, trying osx/gcc
2014-12-06 23:01:41 +00:00
1d45478637 Setup Travis CI integration
Argh.
2014-12-06 21:06:00 +00:00
1bfb59174a Setup Travis CI integration
Apt-get update needed..
2014-12-06 21:04:25 +00:00
83575a464f Setup Travis CI integration
Forgot sudo. Removing apt-get update, probably works without.
2014-12-06 21:01:00 +00:00
3e83de58b5 Setup Travis CI integration 2014-12-06 20:59:14 +00:00
2b0d8447e3 Setup Travis CI integration
Testing
2014-12-06 20:56:34 +00:00
d553cd96b0 Setup Travis CI integration
Testing.
2014-12-06 20:50:27 +00:00
30ee2fed2b Merge branch 'master' of https://github.com/ocornut/imgui 2014-12-06 20:43:13 +00:00
036ed3ea93 OpenGL3 example: unregistered mouse callback for mouse click-release faster than frame interval. 2014-12-06 20:43:08 +00:00
123691023b Merge pull request #94 from emoon/master
Clang warning fixes
2014-12-06 12:59:22 +00:00
317dab5269 Clang warning fixes 2014-12-06 13:49:46 +01:00
e43cd6e97f Added IMGUI_INCLUDE_IMGUI_USER_H 2014-12-05 23:09:43 +00:00
a5cc2e4161 Fixed InputInt() writing to output when it doesn't need to, which break with large int due to int<>float conversions. Added todo note. 2014-12-05 12:34:14 +00:00
6b16424faf Comments. 2014-12-04 11:54:49 +00:00
d133831909 In-code FAQ: added comment about reading WantCaptureMouse / WantCaptureKeyboard 2014-12-04 11:42:13 +00:00
2e5b81627f Examples: DirectX11: moved shader to be close to its usage location, 2014-12-03 18:46:13 +00:00
52b5376d9b Examples: OpenGL3: cleaned up to match features of OpenGL2 example 2014-12-03 18:40:28 +00:00
b02eed3e49 Examples: adding title to the top of each examples. Cleaning up file headers. 2014-12-03 18:29:46 +00:00
90b4ff13fb Ignore list. 2014-12-03 18:19:48 +00:00
6c9edb6db0 Examples: removed LICENSE file from MSVC project. 2014-12-03 18:19:05 +00:00
860cf578f5 Added ImGuiWindowFlags_NoScrollWithMouse flag.
ButtonBehaviour test hovering of CurrentRootWindow (vs CurrentWindow, different for child-windows). This is intentionally meant to fix grabbing the lower-right resize grip when lower-right corner has a child-window, but may be the overall right-er test. Testing out.
2014-12-03 18:17:10 +00:00
e0dc8ac910 Merge pull request #93 from olivierchatry/master
Added OpenGL programmable-pipeline example.
2014-12-03 18:15:42 +00:00
2f176033c6 fixed indentation mix, removed some unused code, updated different callback using the example_opengl code. 2014-12-03 19:11:23 +01:00
a8d2bc69ed added opengl3 sample, mix from @ocornut and @thelinked 2014-12-03 18:37:07 +01:00
63ff0ad0ff Examples: OpenGL: fix accessing libraries via ProjectDir instead of SolutionDir 2014-12-03 12:00:03 +00:00
d31623061f ImVector: private -> protected 2014-12-03 11:56:40 +00:00
bd762b559c DirectX11 example: fixed projection matrix offset. 2014-12-01 09:34:17 +00:00
e6b9950645 Update README.md
Credits+link for stb_textedit.h
2014-11-30 18:06:52 +00:00
b4fd216bd2 DirectX9/DirectX11 example: fixed window initially showing an hourglass cursor. 2014-11-30 18:02:08 +00:00
0730ec7577 Example apps: accumulate mouse wheel to accodomate for slow framerate. 2014-11-30 17:41:08 +00:00
0e6f288a2f DirectX11 example: further tweaks/massaging (-15 lines). Syncing example. 2014-11-30 17:26:44 +00:00
7f804d3d64 Tab->Spaces :( visual studio can't even be trusted for that, oh thanks. 2014-11-30 16:56:35 +00:00
de44af5227 DirectX11 example: closing all handler/resources in Cleanup. 2014-11-30 16:53:33 +00:00
0f29cd7a14 Removed Microsoft IME handler in examples, too confusing. Moved to imgui.cpp instruction block. 2014-11-30 15:54:58 +00:00
a5a84a9b69 Tab->Spaces :( 2014-11-30 15:53:47 +00:00
197b2763fc Fixed DirectX11 example Release build include 2014-11-30 15:51:42 +00:00
df00fa8113 Fixed DirectX11 example to compile with whatever Visual Studio version user has 2014-11-30 15:33:57 +00:00
e835ef1d90 Fix from incorrect change left-over in a31e44b99a 2014-11-30 15:19:39 +00:00
ae75553ba1 Ignore list for new examples structure 2014-11-30 15:01:08 +00:00
2e576de9ca Fix comments 2014-11-30 15:00:07 +00:00
9e16317382 Added DirectX11 example application (code is too long!) 2014-11-30 14:59:21 +00:00
b5acb16378 Examples: created single .sln solution for all example projects. 2014-11-30 12:54:27 +00:00
38164a410d ImStrnicmp tweak 2014-11-30 12:31:43 +00:00
214c967df8 Example code: warning fix + comments. 2014-11-30 12:28:21 +00:00
31654958f9 Merge pull request #92 from memononen/master
Smoother mouse wheel scrolling
2014-11-30 12:25:21 +00:00
a31e44b99a Fixed Clang -Weverything warnings + TODO list entries 2014-11-30 12:21:50 +00:00
54ea495207 Updated example code. 2014-11-30 12:24:27 +02:00
eb789c0288 Smoother scrolling
- changed IO.MouseWheel to float, allows smoother scrolling
2014-11-30 12:20:25 +02:00
e9aead09cb Remove unneeded extra parameter from ImFont::FindGlyph() 2014-11-29 00:04:05 +00:00
e4a79e9fc8 Moved IO.Font*** options to inside the IO.Font-> structure.. Added IO.FontGlobalScale setting (vs Font->Scale) 2014-11-29 00:02:46 +00:00
e27eddfbd2 Grammar fix + ocd alignment 2014-11-28 23:10:43 +00:00
311a2f8328 New version of IMGUI_ONCE_UPON_A_FRAME helper macro 2014-11-28 23:08:45 +00:00
df2ad5e899 Renamed ImBitmapFont -> ImFont, removed abstraction-pretend typedef 2014-11-28 22:38:41 +00:00
07a6ba8aaf Merge branch 'master' of https://github.com/ocornut/imgui 2014-11-28 22:29:07 +00:00
16d6561aba Increased visibility of check box and radio button with smaller size. + comments 2014-11-28 21:53:31 +00:00
abe45e9976 Moved API Breaking Changes section of the documentation above the programmer's FAQ. 2014-11-26 22:27:48 +00:00
c0999495e7 Fixed move-by-word in InputText() - broken 2 days ago, sorry. stb_ expect a define. 2014-11-26 22:19:46 +00:00
b9118750ae Removed IMGUI_ONCE_UPON_A_FRAME in favor of ImGuiOnceUponAFrame which is supported by all compilers 2014-11-26 22:16:38 +00:00
7f6453ca70 Update README.md
Grammar fix
2014-11-25 15:19:05 +00:00
24a9d32531 Update README.md 2014-11-25 15:17:15 +00:00
ec4b510775 Minor tidying & comments 2014-11-24 10:02:39 +00:00
1484799b18 Console example: fixing losing text selection when using TAB completion with no match 2014-11-23 23:50:23 +00:00
895f93f694 Remove unused variables 2014-11-23 23:36:54 +00:00
49defcf083 InputText support for completion/history/custom callback + added fancy completion example in the console demo app
Unfortunately quite messy because of the UTF-8 <> wchar confusion going
around. Not well tested for UTF-8 compliance with non-Ascii characters.
2014-11-23 23:35:26 +00:00
e78c47961e Not word-wrapping on apostrophes 2014-11-21 16:35:35 +00:00
8c4fcf1359 Added ImGuiWindowFlags_AlwaysAutoResize + example app. Calling SetWindowSize(0,0) force an autofit without zero-sizing first. 2014-11-21 16:29:56 +00:00
2322318cac PopStyleVar() fix. OOPS 2014-11-21 14:19:26 +00:00
5f8175abaa Version number 2014-11-21 13:40:38 +00:00
ab4f5e6862 Update README.md 2014-11-21 13:38:09 +00:00
075fe0220e MouseWheel input is normalized 2014-11-21 13:24:57 +00:00
cf037b4769 PushStyleColor/PushStyleVar can be used outside the scope of a window. Added 'count' parameter to PopStyleColor/PopStyleVar 2014-11-21 13:23:22 +00:00
97192606a6 Fixed Tab > space 2014-11-20 15:19:55 +00:00
e90984f638 Update README.md about performance 2014-11-20 12:27:05 +00:00
366516c154 Added "performance" screenshot 2014-11-20 12:10:53 +00:00
a6e0d182b0 Added "performance" screenshot 2014-11-20 12:04:08 +00:00
3572b04c69 ShowTestWindow: fixed example app from not displaying when header is collaposed. 2014-11-20 11:54:13 +00:00
fd8752df8d Style editor: colors list inside a scrolling region 2014-11-20 11:33:40 +00:00
f1dcd72e9f General fixes of Columns() api. User has more flexibility in the way to fill cells. 2014-11-20 11:31:55 +00:00
2aee4419e3 Fixed compatibility with std::vector if user decide to #define ImVector 2014-11-20 08:15:21 +00:00
9f2545e6bb Fixed comment 2014-11-18 10:01:34 +00:00
f3bd033b6d More fixes for ultra pedantic Clang -Weverything 2014-11-18 09:55:31 +00:00
b15532345b Using sqrtf, cosf, sinf. Made STB_TEXTEDIT_ implemtations static. Tweaks. 2014-11-18 07:51:55 +00:00
15436b46e8 Merge pull request #83 from emoon/master
Fixed Clang warnings
2014-11-18 07:40:50 +00:00
b01adf16de Fixed more Clang warnings 2014-11-17 20:37:22 +01:00
428c4d4ece Fixed Clang warnings 2014-11-17 20:35:58 +01:00
172ff0a262 Commenting unnecessary strlen calls that could be removed for speedup 2014-11-17 02:27:26 +09:00
c6f3d0924e Default 'text_end' parameter for low-level AddText/CalcTextSizeA functions 2014-11-17 02:18:37 +09:00
ac40284536 Fixed punctuation. 2014-11-15 13:29:44 +00:00
191e17eaf8 Added IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT 2014-11-15 13:18:25 +00:00
616668dac3 OpenGL example: uses offsetof() macros for vertice definition instead of hardcoded offsets 2014-11-15 13:10:15 +00:00
36e52167da OpenGL example: made the render function save/restore OpenGL state properly-ish 2014-11-15 12:56:41 +00:00
3f85fe2fe7 Cleanup and TODO list items 2014-11-15 12:00:35 +00:00
447cc88e04 Fixed unaligned memory access - fix font loading when building on Emscripten 2014-11-15 11:41:03 +00:00
9c707b6d8f Added assert to catch font data loading failure in a location that's easier to understand 2014-11-14 11:22:35 +09:00
9b5493d1d9 Added assert to catch users using Begin/End without a first NewFrame 2014-11-14 11:17:59 +09:00
8a65d97bf0 Warning fixes (now testing with Clang) 2014-11-12 16:56:42 +09:00
be93b842c1 Merge pull request #77 from ybunyak/master
Fix namespaces for Value() and Color() functions.
2014-11-12 08:48:53 +09:00
7961c53145 Fix namespaces for Value() and Color() functions. 2014-11-12 01:36:34 +02:00
d3bc92a674 Added INDEX to top of imgui.cpp
Explicit namespace prefix on all ImGui:: functions.
Fixed some typos.
2014-11-10 10:29:01 +09:00
4205241e86 PushTextWrapPos() defaults to 0.0 2014-11-10 10:23:06 +09:00
c97636aef4 Fixed lines clockwiseness to be consistent with other primitives. 2014-11-10 09:36:01 +09:00
ee3355fe8e Version number 2014-11-07 17:43:00 +09:00
1e30400f80 Added PushStyleVar(),PopStyleVar() helpers.
BeginChild() allows to specify negative sizes to specify "use remaining minus xx".
Added a simple example console into the demo window.
2014-11-07 17:22:38 +09:00
3a64c77826 Renamed IsHovered() to IsItemHovered() 2014-11-07 15:49:14 +09:00
e19f0d370a Added dummy IMGUI_API definition in front of entry-points for silly DLL action 2014-11-07 15:40:58 +09:00
6c192f3221 Added GetContentRegionMax() supporting columns. Some bug fixes with using columns. 2014-11-07 15:17:04 +09:00
78645a7dba Added word-wrapping API TextWrapped(), PushTextWrapPos(), PopTextWrapPos()
Added word-wrapping sample in the test window.
Added IsItemFocused() to tell if last widget is being focused for keyboard input.
2014-11-07 14:45:56 +09:00
74363c5a43 Fixed column using a "funny scale factor" (non power of two) #67 2014-10-26 21:33:34 +00:00
0b10cf4bd7 Fixed some typos in comments 2014-10-26 21:31:34 +00:00
3d84858755 Made with the NoResize flag can still use auto-fitting. Added SetWindowSize(). 2014-10-26 20:07:15 +00:00
fad5e45d2c Minor tweaks 2014-10-26 19:56:57 +00:00
05a3a9b962 Merge pull request #66 from JarrettBillingsley/master
Added callback versions of PlotLines/PlotHistogram
2014-10-26 20:53:40 +01:00
85eee4a4c5 Added overloads of ImGui::PlotLines and ImGui::PlotHistogram which take a value getter function instead of raw value data, and changed the implementation of the original overloads to use this new implementation. 2014-10-26 12:25:00 -07:00
4c4798546e Merge pull request #1 from ocornut/master
GCC warning fix
2014-10-26 12:22:27 -07:00
f768579377 GCC warning fix 2014-10-26 18:57:19 +00:00
e6eafd6fa8 Fixed warnings for GCC -Wpedantic 2014-10-26 15:08:28 +00:00
29 changed files with 4285 additions and 1530 deletions

9
.gitignore vendored
View File

@ -1,10 +1,19 @@
## Visual Studio files
examples/Debug/*
examples/Release/*
examples/ipch/*
examples/directx9_example/Debug/*
examples/directx9_example/Release/*
examples/directx9_example/ipch/*
examples/directx11_example/Debug/*
examples/directx11_example/Release/*
examples/directx11_example/ipch/*
examples/opengl_example/Debug/*
examples/opengl_example/Release/*
examples/opengl_example/ipch/*
examples/opengl3_example/Debug/*
examples/opengl3_example/Release/*
examples/opengl3_example/ipch/*
*.opensdf
*.sdf
*.suo

17
.travis.yml Normal file
View File

@ -0,0 +1,17 @@
language: cpp
os:
- linux
compiler:
- gcc
- clang
before_install:
- if [ $TRAVIS_OS_NAME == linux ]; then sudo add-apt-repository -y ppa:pyglfw/pyglfw && sudo apt-get update -qq && sudo apt-get install -y --no-install-recommends libglfw3-dev libglew-dev libxrandr-dev libxi-dev libxxf86vm-dev; fi
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glew && brew install glfw3; fi
script:
- make -C examples/opengl_example
- make -C examples/opengl3_example

View File

@ -1,13 +1,21 @@
ImGui
=====
[![Build Status](https://travis-ci.org/ocornut/imgui.svg?branch=master)](https://travis-ci.org/ocornut/imgui)
ImGui is a bloat-free graphical user interface library for C++. It outputs vertex buffers that you can render in your 3D-pipeline enabled application. It is portable, renderer agnostic and carries minimal amount of dependencies (only 3 files are needed). It is based on an "immediate" graphical user interface paradigm which allows you to build user interfaces with ease.
ImGui is a bloat-free graphical user interface library for C++. It outputs vertex buffers that you can render in your 3D-pipeline enabled application. It is portable, renderer agnostic and carries minimal amount of dependencies. It is based on an "immediate" graphical user interface paradigm which allows you to build user interfaces with ease.
ImGui is designed to enable fast iteration and allow programmers to create "content creation" or "debug" tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries
ImGui is designed to enable fast iteration and allow programmers to create "content creation" or "debug" tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
ImGui is particularly suited to integration in 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
After ImGui is setup in your engine, you can use it like in this example:
ImGui is self-contained within 4 files that you can easily copy and compile into your application/engine:
- imgui.cpp
- imgui.h
- imconfig.h (empty by default, user-editable)
- stb_textedit.h
Your code passes mouse/keyboard inputs and settings to ImGui (see example applications for more details). After ImGui is setup, you can use it like in this example:
![screenshot of sample code alongside its output with ImGui](/web/code_sample_01.png?raw=true)
@ -38,9 +46,14 @@ The Immediate Mode GUI paradigm may at first appear unusual to some users. This
Frequently Asked Question
-------------------------
<b>How do you use ImGui on a platform that may not have a mouse and keyboard?</b>
I recommend using [Synergy](http://synergy-project.org). With the uSynergy.c micro client running you can seamlessly use your PC input devices from a video game console or a tablet. ImGui was also designed to function with touch inputs if you increase the padding of widgets to compensate for the lack of precision of touch devices, but it is recommended you use a mouse to allow optimising for screen real-estate.
<b>Where are samples?</b>
The bulk of example user code is contained within the ImGui::ShowTestWindow() function. It covers most features of ImGui so you can read the code and call the function itself to see its output. Ready-to-go example applications covering different versions of OpenGL/DirectX are provided in the examples/ folder.
<b>How do you use ImGui on a platform that may not have a mouse or keyboard?</b>
I recommend using [Synergy](http://synergy-project.org). With the uSynergy.c micro client running on your platform and connecting to your PC, you can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accomodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
<b>I integrated ImGui in my engine and the text or lines are blurry..</b>
@ -51,26 +64,56 @@ I recommend using [Synergy](http://synergy-project.org). With the uSynergy.c mic
Yes. I have written data browsers, debuggers, profilers and all sort of non-trivial tools with the library. There's no reason you cannot, and in my experience the simplicity of the API is very empowering. However note that ImGui is programmer centric and the immediate-mode GUI paradigm might requires a bit of adaptation before you can realize its full potential.
<b>Is ImGui fast?</b>
Down the fundation of its visual design, ImGui is engineered to be fairly performant both in term of CPU and GPU usage. Running elaborate code and creating elaborate UI will of course have a cost but ImGui aims to minimize it.
Mileage may vary but the following screenshot should give you an idea of the cost of running and rendering UI code (In the case of a trivial demo application like this one, your driver/os setup may be a bottleneck and cause higher variation or throttled framerate. Testing performance as part of a real application is recommended).
![performance screenshot](/web/performance_01_close_up.png?raw=true)
This is showing framerate on my 2011 iMac running Windows 7, OpenGL, AMD Radeon HD 6700M. ([click here for the full-size picture](/web/performance_01.png)).
In contrast, librairies featuring higher-quality rendering and layouting techniques may have a higher resources footprint.
<b>Can you reskin the look of ImGui?</b>
Yes, you can alter the look of the interface to some degree: changing colors, sizes and padding, font. However, as ImGui is designed and optimised to create debug tools, the amount of skinning you can apply is limited. There is only so much you can stray away from the default look and feel of the interface. The example below uses modified settings to create a more compact UI with different colors:
Yes, you can alter the look of the interface to some degree: changing colors, sizes and padding, font. However, as ImGui is designed and optimised to create debug tools, the amount of skinning you can apply is limited. There is only so much you can stray away from the default look and feel of the interface. The example below uses modified settings to create a very compact UI with different colors:
![skinning screenshot 1](/web/skinning_sample_01.png?raw=true)
<b>Can you develop features xxxx for ImGui?</b>
<b>Why using C++ (as opposed to C)?</b>
Please use GitHub 'Issues' facilities to suggest and discuss improvements. If you are company and would like specific non-trivial features to be implemented, I am available for hire to work on or with ImGui. Donations are also welcome to support further work on the library.
ImGui takes advantage of a few C++ features for convenience but nothing in the realm of Boost-insanity/quagmire. In particular, function overloading and default parameters are used to make the API easier to use and code more terse. Doing so I believe the API is sitting on a sweet spot and giving up on those features would make the API more cumbersome. Other features such as namespace, constructors and templates (in the case of the ImVector<> class) are also relied on as a convenience but could be removed.
Shall someone wants to use ImGui from another language, it should be possible to wrap ImGui to be used from a raw C API in the future.
Donate
------
<b>Can I donate to support the development of ImGui?</b>
Yes please! I have setup an [**ImGui Patreon page**](http://www.patreon.com/imgui) if you want to donate and enable me to spend more time improving the library. If your company uses ImGui on a commercial project please consider making a small contribution. One-off donations are also greatly appreciated. I am also available for hire to work on or with ImGui. Thanks!
Credits
-------
Developed by [Omar Cornut](http://www.miracleworld.net). The 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).
Embeds [proggy_clean](http://upperbounds.net) font by Tristan Grimmer (MIT license).
Embeds [M+ fonts](http://mplus-fonts.sourceforge.jp/mplus-outline-fonts/index-en.html) font by Coji Morishita (free software license).
Embeds [stb_textedit.h](https://github.com/nothings/stb/) by Sean Barrett (public domain).
Inspiration, feedback, and testing: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. Thanks!
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
ImGui is financially supported on [**Patreon**](http://www.patreon.com/imgui).
Special supporters
- Jetha Chan
Supporters
- Michel Courtine
And other supporters; thanks!
License
-------

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{9F316E83-5AE5-4939-A723-305A94F48005}</ProjectGuid>
<RootNamespace>directx11_example</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>d3d11.lib;d3dcompiler.lib;dxgi.lib;imm32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>d3d11.lib;d3dcompiler.lib;dxgi.lib;imm32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\imconfig.h" />
<ClInclude Include="..\..\imgui.h" />
<ClInclude Include="..\..\stb_textedit.h" />
<ClInclude Include="..\shared\stb_image.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\imgui.cpp" />
<ClCompile Include="main.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="imgui">
<UniqueIdentifier>{0587d7a3-f2ce-4d56-b84f-a0005d3bfce6}</UniqueIdentifier>
</Filter>
<Filter Include="sources">
<UniqueIdentifier>{08e36723-ce4f-4cff-9662-c40801cf1acf}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\imconfig.h">
<Filter>imgui</Filter>
</ClInclude>
<ClInclude Include="..\..\imgui.h">
<Filter>imgui</Filter>
</ClInclude>
<ClInclude Include="..\..\stb_textedit.h">
<Filter>imgui</Filter>
</ClInclude>
<ClInclude Include="..\shared\stb_image.h">
<Filter>sources</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\imgui.cpp">
<Filter>imgui</Filter>
</ClCompile>
<ClCompile Include="main.cpp">
<Filter>sources</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,607 @@
// ImGui - standalone example application for DirectX 11
#include <windows.h>
#define STB_IMAGE_STATIC
#define STB_IMAGE_IMPLEMENTATION
#include "../shared/stb_image.h" // for .png loading
#include "../../imgui.h"
// DirectX 11
#include <d3d11.h>
#include <d3dcompiler.h>
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strdup
static HWND hWnd;
static ID3D11Device* g_pd3dDevice = NULL;
static ID3D11DeviceContext* g_pd3dDeviceImmediateContext = NULL;
static IDXGISwapChain* g_pSwapChain = NULL;
static ID3D11Buffer* g_pVB = NULL;
static ID3D11RenderTargetView* g_mainRenderTargetView;
static ID3D10Blob * g_pVertexShaderBlob = NULL;
static ID3D11VertexShader* g_pVertexShader = NULL;
static ID3D11InputLayout* g_pInputLayout = NULL;
static ID3D11Buffer* g_pVertexConstantBuffer = NULL;
static ID3D10Blob * g_pPixelShaderBlob = NULL;
static ID3D11PixelShader* g_pPixelShader = NULL;
static ID3D11ShaderResourceView*g_pFontTextureView = NULL;
static ID3D11SamplerState* g_pFontSampler = NULL;
static ID3D11BlendState* g_blendState = NULL;
struct CUSTOMVERTEX
{
float pos[2];
float uv[2];
unsigned int col;
};
struct VERTEX_CONSTANT_BUFFER
{
float mvp[4][4];
};
// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure)
// If text or lines are blurry when integrating ImGui in your engine:
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
// - try adjusting ImGui::GetIO().PixelCenterOffset to 0.5f or 0.375f
static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count)
{
size_t total_vtx_count = 0;
for (int n = 0; n < cmd_lists_count; n++)
total_vtx_count += cmd_lists[n]->vtx_buffer.size();
if (total_vtx_count == 0)
return;
// Copy and convert all vertices into a single contiguous buffer
D3D11_MAPPED_SUBRESOURCE mappedResource;
if (g_pd3dDeviceImmediateContext->Map(g_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource) != S_OK)
return;
CUSTOMVERTEX* vtx_dst = (CUSTOMVERTEX*)mappedResource.pData;
for (int n = 0; n < cmd_lists_count; n++)
{
const ImDrawList* cmd_list = cmd_lists[n];
const ImDrawVert* vtx_src = &cmd_list->vtx_buffer[0];
for (size_t i = 0; i < cmd_list->vtx_buffer.size(); i++)
{
vtx_dst->pos[0] = vtx_src->pos.x;
vtx_dst->pos[1] = vtx_src->pos.y;
vtx_dst->uv[0] = vtx_src->uv.x;
vtx_dst->uv[1] = vtx_src->uv.y;
vtx_dst->col = vtx_src->col;
vtx_dst++;
vtx_src++;
}
}
g_pd3dDeviceImmediateContext->Unmap(g_pVB, 0);
// Setup orthographic projection matrix into our constant buffer
{
D3D11_MAPPED_SUBRESOURCE mappedResource;
if (g_pd3dDeviceImmediateContext->Map(g_pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource) != S_OK)
return;
VERTEX_CONSTANT_BUFFER* pConstantBuffer = (VERTEX_CONSTANT_BUFFER*)mappedResource.pData;
const float L = 0.0f;
const float R = ImGui::GetIO().DisplaySize.x;
const float B = ImGui::GetIO().DisplaySize.y;
const float T = 0.0f;
const float mvp[4][4] =
{
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f},
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f,},
{ 0.0f, 0.0f, 0.5f, 0.0f },
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
};
memcpy(&pConstantBuffer->mvp, mvp, sizeof(mvp));
g_pd3dDeviceImmediateContext->Unmap(g_pVertexConstantBuffer, 0);
}
// Setup viewport
{
D3D11_VIEWPORT vp;
memset(&vp, 0, sizeof(D3D11_VIEWPORT));
vp.Width = ImGui::GetIO().DisplaySize.x;
vp.Height = ImGui::GetIO().DisplaySize.y;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
g_pd3dDeviceImmediateContext->RSSetViewports(1, &vp);
}
// Bind shader and vertex buffers
unsigned int stride = sizeof(CUSTOMVERTEX);
unsigned int offset = 0;
g_pd3dDeviceImmediateContext->IASetInputLayout(g_pInputLayout);
g_pd3dDeviceImmediateContext->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset);
g_pd3dDeviceImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
g_pd3dDeviceImmediateContext->VSSetShader(g_pVertexShader, NULL, 0);
g_pd3dDeviceImmediateContext->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer);
g_pd3dDeviceImmediateContext->PSSetShader(g_pPixelShader, NULL, 0);
g_pd3dDeviceImmediateContext->PSSetShaderResources(0, 1, &g_pFontTextureView);
g_pd3dDeviceImmediateContext->PSSetSamplers(0, 1, &g_pFontSampler);
// Setup render state
const float blendFactor[4] = { 0.f, 0.f, 0.f, 0.f };
g_pd3dDeviceImmediateContext->OMSetBlendState(g_blendState, blendFactor, 0xffffffff);
// Render command lists
int vtx_offset = 0;
for (int n = 0; n < cmd_lists_count; n++)
{
// Render command list
const ImDrawList* cmd_list = cmd_lists[n];
for (size_t cmd_i = 0; cmd_i < cmd_list->commands.size(); cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->commands[cmd_i];
const D3D11_RECT r = { (LONG)pcmd->clip_rect.x, (LONG)pcmd->clip_rect.y, (LONG)pcmd->clip_rect.z, (LONG)pcmd->clip_rect.w };
g_pd3dDeviceImmediateContext->RSSetScissorRects(1, &r);
g_pd3dDeviceImmediateContext->Draw(pcmd->vtx_count, vtx_offset);
vtx_offset += pcmd->vtx_count;
}
}
// Restore modified state
g_pd3dDeviceImmediateContext->IASetInputLayout(NULL);
g_pd3dDeviceImmediateContext->PSSetShader(NULL, NULL, 0);
g_pd3dDeviceImmediateContext->VSSetShader(NULL, NULL, 0);
}
HRESULT InitDeviceD3D(HWND hWnd)
{
// Setup swap chain
DXGI_SWAP_CHAIN_DESC sd;
{
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = 2;
sd.BufferDesc.Width = (UINT)ImGui::GetIO().DisplaySize.x;
sd.BufferDesc.Height = (UINT)ImGui::GetIO().DisplaySize.y;
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;
#ifdef _DEBUG
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
D3D_FEATURE_LEVEL featureLevel;
const D3D_FEATURE_LEVEL featureLevelArray[1] = { D3D_FEATURE_LEVEL_11_0, };
if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 1, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceImmediateContext) != S_OK)
return E_FAIL;
// Setup rasterizer
{
D3D11_RASTERIZER_DESC RSDesc;
memset(&RSDesc, 0, sizeof(D3D11_RASTERIZER_DESC));
RSDesc.FillMode = D3D11_FILL_SOLID;
RSDesc.CullMode = D3D11_CULL_NONE;
RSDesc.FrontCounterClockwise = FALSE;
RSDesc.DepthBias = 0;
RSDesc.SlopeScaledDepthBias = 0.0f;
RSDesc.DepthBiasClamp = 0;
RSDesc.DepthClipEnable = TRUE;
RSDesc.ScissorEnable = TRUE;
RSDesc.AntialiasedLineEnable = FALSE;
RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
ID3D11RasterizerState* pRState = NULL;
g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
g_pd3dDeviceImmediateContext->RSSetState(pRState);
pRState->Release();
}
// Create the render target
{
ID3D11Texture2D* pBackBuffer;
D3D11_RENDER_TARGET_VIEW_DESC render_target_view_desc;
ZeroMemory(&render_target_view_desc, sizeof(render_target_view_desc));
render_target_view_desc.Format = sd.BufferDesc.Format;
render_target_view_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
g_pd3dDevice->CreateRenderTargetView(pBackBuffer, &render_target_view_desc, &g_mainRenderTargetView);
g_pd3dDeviceImmediateContext->OMSetRenderTargets(1, &g_mainRenderTargetView, NULL);
pBackBuffer->Release();
}
// Create the vertex shader
{
static const char* vertexShader =
"cbuffer vertexBuffer : register(c0) \
{\
float4x4 ProjectionMatrix; \
};\
struct VS_INPUT\
{\
float2 pos : POSITION;\
float4 col : COLOR0;\
float2 uv : TEXCOORD0;\
};\
\
struct PS_INPUT\
{\
float4 pos : SV_POSITION;\
float4 col : COLOR0;\
float2 uv : TEXCOORD0;\
};\
\
PS_INPUT main(VS_INPUT input)\
{\
PS_INPUT output;\
output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\
output.col = input.col;\
output.uv = input.uv;\
return output;\
}";
D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_5_0", 0, 0, &g_pVertexShaderBlob, NULL);
if (g_pVertexShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
return E_FAIL;
if (g_pd3dDevice->CreateVertexShader((DWORD*)g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), NULL, &g_pVertexShader) != S_OK)
return E_FAIL;
// Create the input layout
D3D11_INPUT_ELEMENT_DESC localLayout[] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, (size_t)(&((CUSTOMVERTEX*)0)->pos), D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((CUSTOMVERTEX*)0)->col), D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((CUSTOMVERTEX*)0)->uv), D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
if (g_pd3dDevice->CreateInputLayout(localLayout, 3, g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK)
return E_FAIL;
// Create the constant buffer
{
D3D11_BUFFER_DESC cbDesc;
cbDesc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER);
cbDesc.Usage = D3D11_USAGE_DYNAMIC;
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
cbDesc.MiscFlags = 0;
g_pd3dDevice->CreateBuffer(&cbDesc, NULL, &g_pVertexConstantBuffer);
}
}
// Create the pixel shader
{
static const char* pixelShader =
"struct PS_INPUT\
{\
float4 pos : SV_POSITION;\
float4 col : COLOR0;\
float2 uv : TEXCOORD0;\
};\
sampler sampler0;\
Texture2D texture0;\
\
float4 main(PS_INPUT input) : SV_Target\
{\
float4 out_col = texture0.Sample(sampler0, input.uv);\
return input.col * out_col;\
}";
D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_5_0", 0, 0, &g_pPixelShaderBlob, NULL);
if (g_pPixelShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
return E_FAIL;
if (g_pd3dDevice->CreatePixelShader((DWORD*)g_pPixelShaderBlob->GetBufferPointer(), g_pPixelShaderBlob->GetBufferSize(), NULL, &g_pPixelShader) != S_OK)
return E_FAIL;
}
// Create the blending setup
{
D3D11_BLEND_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.AlphaToCoverageEnable = false;
desc.RenderTarget[0].BlendEnable = true;
desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
g_pd3dDevice->CreateBlendState(&desc, &g_blendState);
}
return S_OK;
}
void CleanupDevice()
{
if (g_pd3dDeviceImmediateContext) g_pd3dDeviceImmediateContext->ClearState();
// InitImGui
if (g_pFontSampler) g_pFontSampler->Release();
if (g_pFontTextureView) g_pFontTextureView->Release();
if (g_pVB) g_pVB->Release();
// InitDeviceD3D
if (g_blendState) g_blendState->Release();
if (g_pPixelShader) g_pPixelShader->Release();
if (g_pPixelShaderBlob) g_pPixelShaderBlob->Release();
if (g_pVertexConstantBuffer) g_pVertexConstantBuffer->Release();
if (g_pInputLayout) g_pInputLayout->Release();
if (g_pVertexShader) g_pVertexShader->Release();
if (g_pVertexShaderBlob) g_pVertexShaderBlob->Release();
if (g_mainRenderTargetView) g_mainRenderTargetView->Release();
if (g_pSwapChain) g_pSwapChain->Release();
if (g_pd3dDeviceImmediateContext) g_pd3dDeviceImmediateContext->Release();
if (g_pd3dDevice) g_pd3dDevice->Release();
}
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
ImGuiIO& io = ImGui::GetIO();
switch (msg)
{
case WM_LBUTTONDOWN:
io.MouseDown[0] = true;
return true;
case WM_LBUTTONUP:
io.MouseDown[0] = false;
return true;
case WM_RBUTTONDOWN:
io.MouseDown[1] = true;
return true;
case WM_RBUTTONUP:
io.MouseDown[1] = false;
return true;
case WM_MOUSEWHEEL:
io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f;
return true;
case WM_MOUSEMOVE:
// Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
io.MousePos.x = (signed short)(lParam);
io.MousePos.y = (signed short)(lParam >> 16);
return true;
case WM_CHAR:
// You can also use ToAscii()+GetKeyboardState() to retrieve characters.
if (wParam > 0 && wParam < 0x10000)
io.AddInputCharacter((unsigned short)wParam);
return true;
case WM_DESTROY:
CleanupDevice();
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
void InitImGui()
{
RECT rect;
GetClientRect(hWnd, &rect);
int display_w = (int)(rect.right - rect.left);
int display_h = (int)(rect.bottom - rect.top);
ImGuiIO& io = ImGui::GetIO();
io.DisplaySize = ImVec2((float)display_w, (float)display_h); // Display size, in pixels. For clamping windows positions.
io.DeltaTime = 1.0f/60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our time step is variable)
io.PixelCenterOffset = 0.0f; // Align Direct3D Texels
io.KeyMap[ImGuiKey_Tab] = VK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array that we will update during the application lifetime.
io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT;
io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT;
io.KeyMap[ImGuiKey_UpArrow] = VK_UP;
io.KeyMap[ImGuiKey_DownArrow] = VK_UP;
io.KeyMap[ImGuiKey_Home] = VK_HOME;
io.KeyMap[ImGuiKey_End] = VK_END;
io.KeyMap[ImGuiKey_Delete] = VK_DELETE;
io.KeyMap[ImGuiKey_Backspace] = VK_BACK;
io.KeyMap[ImGuiKey_Enter] = VK_RETURN;
io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE;
io.KeyMap[ImGuiKey_A] = 'A';
io.KeyMap[ImGuiKey_C] = 'C';
io.KeyMap[ImGuiKey_V] = 'V';
io.KeyMap[ImGuiKey_X] = 'X';
io.KeyMap[ImGuiKey_Y] = 'Y';
io.KeyMap[ImGuiKey_Z] = 'Z';
io.RenderDrawListsFn = ImImpl_RenderDrawLists;
// Create the vertex buffer
{
D3D11_BUFFER_DESC bufferDesc;
memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC));
bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
bufferDesc.ByteWidth = 10000 * sizeof(CUSTOMVERTEX);
bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
bufferDesc.MiscFlags = 0;
if (g_pd3dDevice->CreateBuffer(&bufferDesc, NULL, &g_pVB) < 0)
{
IM_ASSERT(0);
return;
}
}
// Load font texture
// Default font (embedded in code)
const void* png_data;
unsigned int png_size;
ImGui::GetDefaultFontData(NULL, NULL, &png_data, &png_size);
int tex_x, tex_y, tex_comp;
void* tex_data = stbi_load_from_memory((const unsigned char*)png_data, (int)png_size, &tex_x, &tex_y, &tex_comp, 0);
IM_ASSERT(tex_data != NULL);
{
D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.Width = tex_x;
desc.Height = tex_y;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
ID3D11Texture2D *pTexture = NULL;
D3D11_SUBRESOURCE_DATA subResource;
subResource.pSysMem = tex_data;
subResource.SysMemPitch = tex_x * 4;
subResource.SysMemSlicePitch = 0;
g_pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
// Create texture view
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
ZeroMemory(&srvDesc, sizeof(srvDesc));
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = desc.MipLevels;
srvDesc.Texture2D.MostDetailedMip = 0;
g_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &g_pFontTextureView);
pTexture->Release();
}
// Create texture sampler
{
D3D11_SAMPLER_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
desc.MipLODBias = 0.f;
desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
desc.MinLOD = 0.f;
desc.MaxLOD = 0.f;
g_pd3dDevice->CreateSamplerState(&desc, &g_pFontSampler);
}
}
INT64 ticks_per_second = 0;
INT64 last_time = 0;
void UpdateImGui()
{
ImGuiIO& io = ImGui::GetIO();
// Setup time step
INT64 current_time;
QueryPerformanceCounter((LARGE_INTEGER *)&current_time);
io.DeltaTime = (float)(current_time - last_time) / ticks_per_second;
last_time = current_time;
// Setup inputs
// (we already got mouse position, buttons, wheel from the window message callback)
BYTE keystate[256];
GetKeyboardState(keystate);
for (int i = 0; i < 256; i++)
io.KeysDown[i] = (keystate[i] & 0x80) != 0;
io.KeyCtrl = (keystate[VK_CONTROL] & 0x80) != 0;
io.KeyShift = (keystate[VK_SHIFT] & 0x80) != 0;
// io.MousePos : filled by WM_MOUSEMOVE event
// io.MouseDown : filled by WM_*BUTTON* events
// io.MouseWheel : filled by WM_MOUSEWHEEL events
// Start the frame
ImGui::NewFrame();
}
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
{
// Register the window class
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, "ImGui Example", NULL };
RegisterClassEx(&wc);
// Create the application's window
hWnd = CreateWindow("ImGui Example", "ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second))
return 1;
if (!QueryPerformanceCounter((LARGE_INTEGER *)&last_time))
return 1;
// Initialize Direct3D
if (InitDeviceD3D(hWnd) < 0)
{
CleanupDevice();
UnregisterClass("ImGui Example", wc.hInstance);
return 1;
}
// Show the window
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);
InitImGui();
// Enter the message loop
MSG msg;
ZeroMemory(&msg, sizeof(msg));
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
continue;
}
UpdateImGui();
static bool show_test_window = true;
static bool show_another_window = false;
// 1. Show a simple window
// Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug"
{
static float f;
ImGui::Text("Hello, world!");
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
show_test_window ^= ImGui::Button("Test Window");
show_another_window ^= ImGui::Button("Another Window");
// Calculate and show frame rate
static float ms_per_frame[120] = { 0 };
static int ms_per_frame_idx = 0;
static float ms_per_frame_accum = 0.0f;
ms_per_frame_accum -= ms_per_frame[ms_per_frame_idx];
ms_per_frame[ms_per_frame_idx] = ImGui::GetIO().DeltaTime * 1000.0f;
ms_per_frame_accum += ms_per_frame[ms_per_frame_idx];
ms_per_frame_idx = (ms_per_frame_idx + 1) % 120;
const float ms_per_frame_avg = ms_per_frame_accum / 120;
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", ms_per_frame_avg, 1000.0f / ms_per_frame_avg);
}
// 2. Show another simple window, this time using an explicit Begin/End pair
if (show_another_window)
{
ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100));
ImGui::Text("Hello");
ImGui::End();
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCondition_FirstUseEver); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly!
ImGui::ShowTestWindow(&show_test_window);
}
// Rendering
float clearColor[4] = { 204 / 255.f, 153 / 255.f, 153 / 255.f };
g_pd3dDeviceImmediateContext->ClearRenderTargetView(g_mainRenderTargetView, clearColor);
ImGui::Render();
g_pSwapChain->Present(0, 0);
}
ImGui::Shutdown();
UnregisterClass("ImGui Example", wc.hInstance);
return 0;
}

View File

@ -1,20 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "directx9_example", "directx9_example.vcxproj", "{4165A294-21F2-44CA-9B38-E3F935ABADF5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4165A294-21F2-44CA-9B38-E3F935ABADF5}.Debug|Win32.ActiveCfg = Debug|Win32
{4165A294-21F2-44CA-9B38-E3F935ABADF5}.Debug|Win32.Build.0 = Debug|Win32
{4165A294-21F2-44CA-9B38-E3F935ABADF5}.Release|Win32.ActiveCfg = Release|Win32
{4165A294-21F2-44CA-9B38-E3F935ABADF5}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -46,7 +46,7 @@
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(DXSDK_DIR)Lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;winmm.lib;comctl32.lib;gdi32.lib;imm32.lib;user32.lib</AdditionalDependencies>
<AdditionalDependencies>d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;imm32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>
</SubSystem>
</Link>
@ -64,7 +64,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(DXSDK_DIR)Lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;winmm.lib;comctl32.lib;gdi32.lib;imm32.lib;user32.lib</AdditionalDependencies>
<AdditionalDependencies>d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;imm32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>
</SubSystem>
</Link>
@ -78,9 +78,6 @@
<ClInclude Include="..\..\imgui.h" />
<ClInclude Include="..\..\stb_textedit.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\LICENSE" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

View File

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="imgui">
<UniqueIdentifier>{ac86c4ce-1d96-47a9-9ace-f8970c3bd485}</UniqueIdentifier>
</Filter>
<Filter Include="sources">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="imgui">
<UniqueIdentifier>{a82cba23-9de0-45c2-b1e3-2eb1666702de}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
@ -28,9 +28,4 @@
<Filter>imgui</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\LICENSE">
<Filter>imgui</Filter>
</None>
</ItemGroup>
</Project>

View File

@ -1,23 +1,25 @@
// ImGui - standalone example application for DirectX 9
#include <windows.h>
#include <imm.h>
#include <mmsystem.h>
#include "../../imgui.h"
// DirectX 9
#include <d3dx9.h>
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>
#include "../../imgui.h"
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strdup
static HWND hWnd;
static HWND hWnd;
static LPDIRECT3D9 g_pD3D = NULL; // Used to create the D3DDevice
static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; // Our rendering device
static LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; // Buffer to hold vertices
static LPDIRECT3DTEXTURE9 g_pTexture = NULL; // Our texture
struct CUSTOMVERTEX
{
D3DXVECTOR3 position;
D3DCOLOR color;
float tu, tv;
D3DXVECTOR3 pos;
D3DCOLOR col;
D3DXVECTOR2 uv;
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
@ -43,12 +45,12 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
const ImDrawVert* vtx_src = &cmd_list->vtx_buffer[0];
for (size_t i = 0; i < cmd_list->vtx_buffer.size(); i++)
{
vtx_dst->position.x = vtx_src->pos.x;
vtx_dst->position.y = vtx_src->pos.y;
vtx_dst->position.z = 0.0f;
vtx_dst->color = (vtx_src->col & 0xFF00FF00) | ((vtx_src->col & 0xFF0000)>>16) | ((vtx_src->col & 0xFF) << 16); // RGBA --> ARGB for DirectX9
vtx_dst->tu = vtx_src->uv.x;
vtx_dst->tv = vtx_src->uv.y;
vtx_dst->pos.x = vtx_src->pos.x;
vtx_dst->pos.y = vtx_src->pos.y;
vtx_dst->pos.z = 0.0f;
vtx_dst->col = (vtx_src->col & 0xFF00FF00) | ((vtx_src->col & 0xFF0000)>>16) | ((vtx_src->col & 0xFF) << 16); // RGBA --> ARGB for DirectX9
vtx_dst->uv.x = vtx_src->uv.x;
vtx_dst->uv.y = vtx_src->uv.y;
vtx_dst++;
vtx_src++;
}
@ -92,9 +94,9 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
{
// Render command list
const ImDrawList* cmd_list = cmd_lists[n];
const ImDrawCmd* pcmd_end = cmd_list->commands.end();
for (const ImDrawCmd* pcmd = cmd_list->commands.begin(); pcmd != pcmd_end; pcmd++)
for (size_t cmd_i = 0; cmd_i < cmd_list->commands.size(); cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->commands[cmd_i];
const RECT r = { (LONG)pcmd->clip_rect.x, (LONG)pcmd->clip_rect.y, (LONG)pcmd->clip_rect.z, (LONG)pcmd->clip_rect.w };
g_pd3dDevice->SetScissorRect(&r);
g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, vtx_offset, pcmd->vtx_count/3);
@ -103,7 +105,7 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
}
}
HRESULT InitD3D(HWND hWnd)
HRESULT InitDeviceD3D(HWND hWnd)
{
if (NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
return E_FAIL;
@ -124,19 +126,18 @@ HRESULT InitD3D(HWND hWnd)
return S_OK;
}
void Cleanup()
void CleanupDevice()
{
if (g_pTexture != NULL)
g_pTexture->Release();
// InitImGui
if (g_pVB) g_pVB->Release();
if (g_pd3dDevice != NULL)
g_pd3dDevice->Release();
if (g_pD3D != NULL)
g_pD3D->Release();
// InitDeviceD3D
if (g_pTexture) g_pTexture->Release();
if (g_pd3dDevice) g_pd3dDevice->Release();
if (g_pD3D) g_pD3D->Release();
}
LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
ImGuiIO& io = ImGui::GetIO();
switch (msg)
@ -154,8 +155,7 @@ LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
io.MouseDown[1] = false;
return true;
case WM_MOUSEWHEEL:
// Mouse wheel: -1,0,+1
io.MouseWheel = GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1 : -1;
io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f;
return true;
case WM_MOUSEMOVE:
// Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
@ -168,36 +168,25 @@ LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
io.AddInputCharacter((unsigned short)wParam);
return true;
case WM_DESTROY:
Cleanup();
CleanupDevice();
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
// Notify OS Input Method Editor of text input position (e.g. when using Japanese/Chinese inputs, otherwise this isn't needed)
static void ImImpl_ImeSetInputScreenPosFn(int x, int y)
{
if (HIMC himc = ImmGetContext(hWnd))
{
COMPOSITIONFORM cf;
cf.ptCurrentPos.x = x;
cf.ptCurrentPos.y = y;
cf.dwStyle = CFS_FORCE_POSITION;
ImmSetCompositionWindow(himc, &cf);
}
}
void InitImGui()
{
RECT rect;
GetClientRect(hWnd, &rect);
int display_w = (int)(rect.right - rect.left);
int display_h = (int)(rect.bottom - rect.top);
ImGuiIO& io = ImGui::GetIO();
io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top)); // Display size, in pixels. For clamping windows positions.
io.DeltaTime = 1.0f/60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our timestep is variable)
io.PixelCenterOffset = 0.0f; // Align Direct3D Texels
io.KeyMap[ImGuiKey_Tab] = VK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array that we will update during the application lifetime.
io.DisplaySize = ImVec2((float)display_w, (float)display_h); // Display size, in pixels. For clamping windows positions.
io.DeltaTime = 1.0f/60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our time step is variable)
io.PixelCenterOffset = 0.0f; // Align Direct3D Texels
io.KeyMap[ImGuiKey_Tab] = VK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array that we will update during the application lifetime.
io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT;
io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT;
io.KeyMap[ImGuiKey_UpArrow] = VK_UP;
@ -216,7 +205,6 @@ void InitImGui()
io.KeyMap[ImGuiKey_Z] = 'Z';
io.RenderDrawListsFn = ImImpl_RenderDrawLists;
io.ImeSetInputScreenPosFn = ImImpl_ImeSetInputScreenPosFn;
// Create the vertex buffer
if (g_pd3dDevice->CreateVertexBuffer(10000 * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL) < 0)
@ -237,17 +225,17 @@ void InitImGui()
}
INT64 ticks_per_second = 0;
INT64 time = 0;
INT64 last_time = 0;
void UpdateImGui()
{
ImGuiIO& io = ImGui::GetIO();
// Setup timestep
// Setup time step
INT64 current_time;
QueryPerformanceCounter((LARGE_INTEGER *)&current_time);
io.DeltaTime = (float)(current_time - time) / ticks_per_second;
time = current_time;
io.DeltaTime = (float)(current_time - last_time) / ticks_per_second;
last_time = current_time;
// Setup inputs
// (we already got mouse position, buttons, wheel from the window message callback)
@ -268,7 +256,7 @@ void UpdateImGui()
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
{
// Register the window class
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, L"ImGui Example", NULL };
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, L"ImGui Example", NULL };
RegisterClassEx(&wc);
// Create the application's window
@ -276,14 +264,13 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second))
return 1;
if (!QueryPerformanceCounter((LARGE_INTEGER *)&time))
if (!QueryPerformanceCounter((LARGE_INTEGER *)&last_time))
return 1;
// Initialize Direct3D
if (InitD3D(hWnd) < 0)
if (InitDeviceD3D(hWnd) < 0)
{
if (g_pVB)
g_pVB->Release();
CleanupDevice();
UnregisterClass(L"ImGui Example", wc.hInstance);
return 1;
}
@ -320,7 +307,7 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
show_test_window ^= ImGui::Button("Test Window");
show_another_window ^= ImGui::Button("Another Window");
// Calculate and show framerate
// Calculate and show frame rate
static float ms_per_frame[120] = { 0 };
static int ms_per_frame_idx = 0;
static float ms_per_frame_accum = 0.0f;
@ -343,7 +330,7 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
if (show_test_window)
{
ImGui::SetNewWindowDefaultPos(ImVec2(650, 20)); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly!
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCondition_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
}
@ -362,9 +349,6 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
ImGui::Shutdown();
if (g_pVB)
g_pVB->Release();
UnregisterClass(L"ImGui Example", wc.hInstance);
return 0;
}

View File

@ -0,0 +1,38 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl_example", "opengl_example\opengl_example.vcxproj", "{9CDA7840-B7A5-496D-A527-E95571496D18}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "directx9_example", "directx9_example\directx9_example.vcxproj", "{4165A294-21F2-44CA-9B38-E3F935ABADF5}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "directx11_example", "directx11_example\directx11_example.vcxproj", "{9F316E83-5AE5-4939-A723-305A94F48005}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl3_example", "opengl3_example\opengl3_example.vcxproj", "{4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9CDA7840-B7A5-496D-A527-E95571496D18}.Debug|Win32.ActiveCfg = Debug|Win32
{9CDA7840-B7A5-496D-A527-E95571496D18}.Debug|Win32.Build.0 = Debug|Win32
{9CDA7840-B7A5-496D-A527-E95571496D18}.Release|Win32.ActiveCfg = Release|Win32
{9CDA7840-B7A5-496D-A527-E95571496D18}.Release|Win32.Build.0 = Release|Win32
{4165A294-21F2-44CA-9B38-E3F935ABADF5}.Debug|Win32.ActiveCfg = Debug|Win32
{4165A294-21F2-44CA-9B38-E3F935ABADF5}.Debug|Win32.Build.0 = Debug|Win32
{4165A294-21F2-44CA-9B38-E3F935ABADF5}.Release|Win32.ActiveCfg = Release|Win32
{4165A294-21F2-44CA-9B38-E3F935ABADF5}.Release|Win32.Build.0 = Release|Win32
{9F316E83-5AE5-4939-A723-305A94F48005}.Debug|Win32.ActiveCfg = Debug|Win32
{9F316E83-5AE5-4939-A723-305A94F48005}.Debug|Win32.Build.0 = Debug|Win32
{9F316E83-5AE5-4939-A723-305A94F48005}.Release|Win32.ActiveCfg = Release|Win32
{9F316E83-5AE5-4939-A723-305A94F48005}.Release|Win32.Build.0 = Release|Win32
{4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}.Debug|Win32.ActiveCfg = Debug|Win32
{4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}.Debug|Win32.Build.0 = Debug|Win32
{4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}.Release|Win32.ActiveCfg = Release|Win32
{4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,52 @@
#
# Cross Platform Make file
#
# Compatible with Ubuntu 14.04.1 and Mac OS X
#
#
# if you using Mac OS X:
# You should install glew via homebrew
# brew install glew
# Also you'll need glfw
# http://www.glfw.org
#
#CXX = g++
OBJS = main.o
OBJS += ../../imgui.o
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S), Linux) #LINUX
ECHO_MESSAGE = "Linux"
CXXFLAGS = -I../../ `pkg-config --cflags glfw3`
CXXFLAGS += -Wall
LIBS = `pkg-config --static --libs glfw3` -lGLEW
endif
ifeq ($(UNAME_S), Darwin) #APPLE
ECHO_MESSAGE = "Mac OS X"
LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo
LIBS += -L/usr/local/Cellar/glew/1.10.0/lib -L/usr/local/lib
LIBS += -lglew -lglfw3
CXXFLAGS = -I../../ -I/usr/local/Cellar/glew/1.10.0/include -I/usr/local/include
CXXFLAGS += -Wall
# CXXFLAGS += -D__APPLE__
endif
.cpp.o:
$(CXX) $(CXXFLAGS) -c -o $@ $<
all:imgui_example
@echo Build complete for $(ECHO_MESSAGE)
imgui_example:$(OBJS)
$(CXX) -o imgui_example $(OBJS) $(CXXFLAGS) $(LIBS)
clean:
rm $(OBJS)

View File

@ -0,0 +1,392 @@
// ImGui - standalone example application for OpenGL 3, using programmable pipeline
#ifdef _MSC_VER
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
#endif
#ifdef __clang__
#pragma clang diagnostic ignored "-Wunused-function" // warning: unused function
#endif
#include "../../imgui.h"
#define STB_IMAGE_STATIC
#define STB_IMAGE_IMPLEMENTATION
#include "../shared/stb_image.h" // stb_image.h for PNG loading
// Glfw/Glew
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
static GLFWwindow* window;
static GLuint fontTex;
static bool mousePressed[2] = { false, false };
// Shader variables
static int shader_handle, vert_handle, frag_handle;
static int texture_location, ortho_location;
static int position_location, uv_location, colour_location;
static size_t vbo_max_size = 20000;
static unsigned int vbo_handle, vao_handle;
// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure)
// If text or lines are blurry when integrating ImGui in your engine:
// - try adjusting ImGui::GetIO().PixelCenterOffset to 0.0f or 0.5f
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count)
{
if (cmd_lists_count == 0)
return;
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glEnable(GL_SCISSOR_TEST);
// Setup texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, fontTex);
// Setup orthographic projection matrix
const float width = ImGui::GetIO().DisplaySize.x;
const float height = ImGui::GetIO().DisplaySize.y;
const float ortho_projection[4][4] =
{
{ 2.0f/width, 0.0f, 0.0f, 0.0f },
{ 0.0f, 2.0f/-height, 0.0f, 0.0f },
{ 0.0f, 0.0f, -1.0f, 0.0f },
{ -1.0f, 1.0f, 0.0f, 1.0f },
};
glUseProgram(shader_handle);
glUniform1i(texture_location, 0);
glUniformMatrix4fv(ortho_location, 1, GL_FALSE, &ortho_projection[0][0]);
// Grow our buffer according to what we need
size_t total_vtx_count = 0;
for (int n = 0; n < cmd_lists_count; n++)
total_vtx_count += cmd_lists[n]->vtx_buffer.size();
glBindBuffer(GL_ARRAY_BUFFER, vbo_handle);
size_t neededBufferSize = total_vtx_count * sizeof(ImDrawVert);
if (neededBufferSize > vbo_max_size)
{
vbo_max_size = neededBufferSize + 5000; // Grow buffer
glBufferData(GL_ARRAY_BUFFER, vbo_max_size, NULL, GL_STREAM_DRAW);
}
// Copy and convert all vertices into a single contiguous buffer
unsigned char* buffer_data = (unsigned char*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
if (!buffer_data)
return;
for (int n = 0; n < cmd_lists_count; n++)
{
const ImDrawList* cmd_list = cmd_lists[n];
memcpy(buffer_data, &cmd_list->vtx_buffer[0], cmd_list->vtx_buffer.size() * sizeof(ImDrawVert));
buffer_data += cmd_list->vtx_buffer.size() * sizeof(ImDrawVert);
}
glUnmapBuffer(GL_ARRAY_BUFFER);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(vao_handle);
int cmd_offset = 0;
for (int n = 0; n < cmd_lists_count; n++)
{
const ImDrawList* cmd_list = cmd_lists[n];
int vtx_offset = cmd_offset;
const ImDrawCmd* pcmd_end = cmd_list->commands.end();
for (const ImDrawCmd* pcmd = cmd_list->commands.begin(); pcmd != pcmd_end; pcmd++)
{
glScissor((int)pcmd->clip_rect.x, (int)(height - pcmd->clip_rect.w), (int)(pcmd->clip_rect.z - pcmd->clip_rect.x), (int)(pcmd->clip_rect.w - pcmd->clip_rect.y));
glDrawArrays(GL_TRIANGLES, vtx_offset, pcmd->vtx_count);
vtx_offset += pcmd->vtx_count;
}
cmd_offset = vtx_offset;
}
// Restore modified state
glBindVertexArray(0);
glUseProgram(0);
glDisable(GL_SCISSOR_TEST);
glBindTexture(GL_TEXTURE_2D, 0);
}
static const char* ImImpl_GetClipboardTextFn()
{
return glfwGetClipboardString(window);
}
static void ImImpl_SetClipboardTextFn(const char* text)
{
glfwSetClipboardString(window, text);
}
// GLFW callbacks to get events
static void glfw_error_callback(int error, const char* description)
{
fputs(description, stderr);
}
static void glfw_mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
{
if (action == GLFW_PRESS && button >= 0 && button < 2)
mousePressed[button] = true;
}
static void glfw_scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
ImGuiIO& io = ImGui::GetIO();
io.MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines.
}
static void glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
ImGuiIO& io = ImGui::GetIO();
if (action == GLFW_PRESS)
io.KeysDown[key] = true;
if (action == GLFW_RELEASE)
io.KeysDown[key] = false;
io.KeyCtrl = (mods & GLFW_MOD_CONTROL) != 0;
io.KeyShift = (mods & GLFW_MOD_SHIFT) != 0;
}
static void glfw_char_callback(GLFWwindow* window, unsigned int c)
{
if (c > 0 && c < 0x10000)
ImGui::GetIO().AddInputCharacter((unsigned short)c);
}
// OpenGL code based on http://open.gl tutorials
void InitGL()
{
glfwSetErrorCallback(glfw_error_callback);
if (!glfwInit())
exit(1);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow(1280, 720, "ImGui OpenGL example", NULL, NULL);
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, glfw_key_callback);
glfwSetMouseButtonCallback(window, glfw_mouse_button_callback);
glfwSetScrollCallback(window, glfw_scroll_callback);
glfwSetCharCallback(window, glfw_char_callback);
glewExperimental = GL_TRUE;
GLenum err = glewInit();
if (GLEW_OK != err)
fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
const GLchar *vertex_shader =
"#version 330\n"
"uniform mat4 ortho;\n"
"in vec2 Position;\n"
"in vec2 UV;\n"
"in vec4 Colour;\n"
"out vec2 Frag_UV;\n"
"out vec4 Frag_Colour;\n"
"void main()\n"
"{\n"
" Frag_UV = UV;\n"
" Frag_Colour = Colour;\n"
" gl_Position = ortho*vec4(Position.xy,0,1);\n"
"}\n";
const GLchar* fragment_shader =
"#version 330\n"
"uniform sampler2D Texture;\n"
"in vec2 Frag_UV;\n"
"in vec4 Frag_Colour;\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor = Frag_Colour * texture( Texture, Frag_UV.st);\n"
"}\n";
shader_handle = glCreateProgram();
vert_handle = glCreateShader(GL_VERTEX_SHADER);
frag_handle = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(vert_handle, 1, &vertex_shader, 0);
glShaderSource(frag_handle, 1, &fragment_shader, 0);
glCompileShader(vert_handle);
glCompileShader(frag_handle);
glAttachShader(shader_handle, vert_handle);
glAttachShader(shader_handle, frag_handle);
glLinkProgram(shader_handle);
texture_location = glGetUniformLocation(shader_handle, "Texture");
ortho_location = glGetUniformLocation(shader_handle, "ortho");
position_location = glGetAttribLocation(shader_handle, "Position");
uv_location = glGetAttribLocation(shader_handle, "UV");
colour_location = glGetAttribLocation(shader_handle, "Colour");
glGenBuffers(1, &vbo_handle);
glBindBuffer(GL_ARRAY_BUFFER, vbo_handle);
glBufferData(GL_ARRAY_BUFFER, vbo_max_size, NULL, GL_DYNAMIC_DRAW);
glGenVertexArrays(1, &vao_handle);
glBindVertexArray(vao_handle);
glBindBuffer(GL_ARRAY_BUFFER, vbo_handle);
glEnableVertexAttribArray(position_location);
glEnableVertexAttribArray(uv_location);
glEnableVertexAttribArray(colour_location);
glVertexAttribPointer(position_location, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos));
glVertexAttribPointer(uv_location, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv));
glVertexAttribPointer(colour_location, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col));
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void InitImGui()
{
ImGuiIO& io = ImGui::GetIO();
io.DeltaTime = 1.0f / 60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our timestep is variable)
io.PixelCenterOffset = 0.5f; // Align OpenGL texels
io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT;
io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT;
io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP;
io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN;
io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME;
io.KeyMap[ImGuiKey_End] = GLFW_KEY_END;
io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE;
io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE;
io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER;
io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE;
io.KeyMap[ImGuiKey_A] = GLFW_KEY_A;
io.KeyMap[ImGuiKey_C] = GLFW_KEY_C;
io.KeyMap[ImGuiKey_V] = GLFW_KEY_V;
io.KeyMap[ImGuiKey_X] = GLFW_KEY_X;
io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y;
io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z;
io.RenderDrawListsFn = ImImpl_RenderDrawLists;
io.SetClipboardTextFn = ImImpl_SetClipboardTextFn;
io.GetClipboardTextFn = ImImpl_GetClipboardTextFn;
// Load font texture
glGenTextures(1, &fontTex);
glBindTexture(GL_TEXTURE_2D, fontTex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
const void* png_data;
unsigned int png_size;
ImGui::GetDefaultFontData(NULL, NULL, &png_data, &png_size);
int tex_x, tex_y, tex_comp;
void* tex_data = stbi_load_from_memory((const unsigned char*)png_data, (int)png_size, &tex_x, &tex_y, &tex_comp, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_x, tex_y, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_data);
stbi_image_free(tex_data);
}
void UpdateImGui()
{
ImGuiIO& io = ImGui::GetIO();
// Setup resolution (every frame to accommodate for window resizing)
int w, h;
int display_w, display_h;
glfwGetWindowSize(window, &w, &h);
glfwGetFramebufferSize(window, &display_w, &display_h);
io.DisplaySize = ImVec2((float)display_w, (float)display_h); // Display size, in pixels. For clamping windows positions.
// Setup time step
static double time = 0.0f;
const double current_time = glfwGetTime();
io.DeltaTime = (float)(current_time - time);
time = current_time;
// Setup inputs
// (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents())
double mouse_x, mouse_y;
glfwGetCursorPos(window, &mouse_x, &mouse_y);
mouse_x *= (float)display_w / w; // Convert mouse coordinates to pixels
mouse_y *= (float)display_h / h;
io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
io.MouseDown[0] = mousePressed[0] || glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.
io.MouseDown[1] = mousePressed[1] || glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) != 0;
// Start the frame
ImGui::NewFrame();
}
// Application code
int main(int argc, char** argv)
{
InitGL();
InitImGui();
while (!glfwWindowShouldClose(window))
{
ImGuiIO& io = ImGui::GetIO();
io.MouseWheel = 0;
mousePressed[0] = mousePressed[1] = false;
glfwPollEvents();
UpdateImGui();
static bool show_test_window = true;
static bool show_another_window = false;
// 1. Show a simple window
// Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug"
{
static float f;
ImGui::Text("Hello, world!");
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
show_test_window ^= ImGui::Button("Test Window");
show_another_window ^= ImGui::Button("Another Window");
// Calculate and show frame rate
static float ms_per_frame[120] = { 0 };
static int ms_per_frame_idx = 0;
static float ms_per_frame_accum = 0.0f;
ms_per_frame_accum -= ms_per_frame[ms_per_frame_idx];
ms_per_frame[ms_per_frame_idx] = ImGui::GetIO().DeltaTime * 1000.0f;
ms_per_frame_accum += ms_per_frame[ms_per_frame_idx];
ms_per_frame_idx = (ms_per_frame_idx + 1) % 120;
const float ms_per_frame_avg = ms_per_frame_accum / 120;
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", ms_per_frame_avg, 1000.0f / ms_per_frame_avg);
}
// 2. Show another simple window, this time using an explicit Begin/End pair
if (show_another_window)
{
ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100));
ImGui::Text("Hello");
ImGui::End();
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCondition_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
}
// Rendering
glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
glClearColor(0.8f, 0.6f, 0.6f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
ImGui::Render();
glfwSwapBuffers(window);
}
// Cleanup
if (vao_handle) glDeleteVertexArrays(1, &vao_handle);
if (vbo_handle) glDeleteBuffers(1, &vbo_handle);
glDetachShader(shader_handle, vert_handle);
glDetachShader(shader_handle, frag_handle);
glDeleteShader(vert_handle);
glDeleteShader(frag_handle);
glDeleteProgram(shader_handle);
ImGui::Shutdown();
glfwTerminate();
return 0;
}

View File

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{4a1fb5ea-22f5-42a8-ab92-1d2df5d47fb9}</ProjectGuid>
<RootNamespace>opengl3_example</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(ProjectDir)..\opengl_example\glfw\include;$(ProjectDir)..\opengl_example\glew\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(ProjectDir)..\opengl_example\glfw\lib-msvc100;$(ProjectDir)..\opengl_example\glew\lib\Release\Win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>opengl32.lib;imm32.lib;glfw3.lib;glew32s.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>NotSet</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(ProjectDir)..\opengl_example\glfw\include;$(ProjectDir)..\opengl_example\glew\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(ProjectDir)..\opengl_example\glfw\lib-msvc100;$(ProjectDir)..\opengl_example\glew\lib\Release\Win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>opengl32.lib;imm32.lib;glfw3.lib;glew32s.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>NotSet</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\imgui.cpp" />
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\imconfig.h" />
<ClInclude Include="..\..\imgui.h" />
<ClInclude Include="..\..\stb_textedit.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="imgui">
<UniqueIdentifier>{20b90ce4-7fcb-4731-b9a0-075f875de82d}</UniqueIdentifier>
</Filter>
<Filter Include="sources">
<UniqueIdentifier>{f18ab499-84e1-499f-8eff-9754361e0e52}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>sources</Filter>
</ClCompile>
<ClCompile Include="..\..\imgui.cpp">
<Filter>imgui</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\imconfig.h">
<Filter>imgui</Filter>
</ClInclude>
<ClInclude Include="..\..\imgui.h">
<Filter>imgui</Filter>
</ClInclude>
<ClInclude Include="..\..\stb_textedit.h">
<Filter>imgui</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -11,7 +11,7 @@
# http://www.glfw.org
#
CXX = g++
#CXX = g++
OBJS = main.o
OBJS += ../../imgui.o
@ -22,6 +22,7 @@ UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S), Linux) #LINUX
ECHO_MESSAGE = "Linux"
CXXFLAGS = -I../../ `pkg-config --cflags glfw3`
CXXFLAGS += -Wall
LIBS = `pkg-config --static --libs glfw3` -lGLEW
endif
@ -32,11 +33,9 @@ ifeq ($(UNAME_S), Darwin) #APPLE
LIBS += -L/usr/local/Cellar/glew/1.10.0/lib -L/usr/local/lib
LIBS += -lglew -lglfw3
CXXFLAGS = -I/usr/local/Cellar/glew/1.10.0/include -I/usr/local/include
CXXFLAGS += -I../../
CXXFLAGS = -I../../ -I/usr/local/Cellar/glew/1.10.0/include -I/usr/local/include
CXXFLAGS += -Wall
# CXXFLAGS += -D__APPLE__
endif
.cpp.o:

View File

@ -1,26 +1,26 @@
#ifdef _MSC_VER
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
#include <Windows.h>
#include <Imm.h>
#endif
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h" // for .png loading
#include "../../imgui.h"
// ImGui - standalone example application for OpenGL 2, using fixed pipeline
// glew & glfw
#ifdef _MSC_VER
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
#endif
#ifdef __clang__
#pragma clang diagnostic ignored "-Wunused-function" // warning: unused function
#endif
#include "../../imgui.h"
#define STB_IMAGE_STATIC
#define STB_IMAGE_IMPLEMENTATION
#include "../shared/stb_image.h" // stb_image.h for PNG loading
// Glfw/Glew
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#ifdef _MSC_VER
#define GLFW_EXPOSE_NATIVE_WIN32
#define GLFW_EXPOSE_NATIVE_WGL
#include <GLFW/glfw3native.h>
#endif
#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
static GLFWwindow* window;
static GLuint fontTex;
static bool mousePressed[2] = { false, false };
static ImVec2 mousePosScale(1.0f, 1.0f);
// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure)
// If text or lines are blurry when integrating ImGui in your engine:
@ -34,6 +34,7 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
// We are using the OpenGL fixed pipeline to make the example code simpler to read!
// A probable faster way to render would be to collate all vertices from all cmd_lists into a single vertex buffer.
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers.
glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
@ -51,33 +52,41 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
const float width = ImGui::GetIO().DisplaySize.x;
const float height = ImGui::GetIO().DisplaySize.y;
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0.0f, width, height, 0.0f, -1.0f, +1.0f);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
// Render command lists
for (int n = 0; n < cmd_lists_count; n++)
{
const ImDrawList* cmd_list = cmd_lists[n];
const unsigned char* vtx_buffer = (const unsigned char*)cmd_list->vtx_buffer.begin();
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer));
glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer+8));
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer+16));
const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->vtx_buffer.front();
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos)));
glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv)));
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col)));
int vtx_offset = 0;
const ImDrawCmd* pcmd_end = cmd_list->commands.end();
for (const ImDrawCmd* pcmd = cmd_list->commands.begin(); pcmd != pcmd_end; pcmd++)
for (size_t cmd_i = 0; cmd_i < cmd_list->commands.size(); cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->commands[cmd_i];
glScissor((int)pcmd->clip_rect.x, (int)(height - pcmd->clip_rect.w), (int)(pcmd->clip_rect.z - pcmd->clip_rect.x), (int)(pcmd->clip_rect.w - pcmd->clip_rect.y));
glDrawArrays(GL_TRIANGLES, vtx_offset, pcmd->vtx_count);
vtx_offset += pcmd->vtx_count;
}
}
glDisable(GL_SCISSOR_TEST);
// Restore modified state
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glPopAttrib();
}
// NB: ImGui already provide OS clipboard support for Windows so this isn't needed if you are using Windows only.
@ -91,22 +100,6 @@ static void ImImpl_SetClipboardTextFn(const char* text)
glfwSetClipboardString(window, text);
}
#ifdef _MSC_VER
// Notify OS Input Method Editor of text input position (e.g. when using Japanese/Chinese inputs, otherwise this isn't needed)
static void ImImpl_ImeSetInputScreenPosFn(int x, int y)
{
HWND hwnd = glfwGetWin32Window(window);
if (HIMC himc = ImmGetContext(hwnd))
{
COMPOSITIONFORM cf;
cf.ptCurrentPos.x = x;
cf.ptCurrentPos.y = y;
cf.dwStyle = CFS_FORCE_POSITION;
ImmSetCompositionWindow(himc, &cf);
}
}
#endif
// GLFW callbacks to get events
static void glfw_error_callback(int error, const char* description)
{
@ -122,7 +115,7 @@ static void glfw_mouse_button_callback(GLFWwindow* window, int button, int actio
static void glfw_scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
ImGuiIO& io = ImGui::GetIO();
io.MouseWheel = (yoffset != 0.0f) ? yoffset > 0.0f ? 1 : - 1 : 0; // Mouse wheel: -1,0,+1
io.MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines.
}
static void glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
@ -150,7 +143,6 @@ void InitGL()
if (!glfwInit())
exit(1);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
window = glfwCreateWindow(1280, 720, "ImGui OpenGL example", NULL, NULL);
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, glfw_key_callback);
@ -163,18 +155,10 @@ void InitGL()
void InitImGui()
{
int w, h;
int fb_w, fb_h;
glfwGetWindowSize(window, &w, &h);
glfwGetFramebufferSize(window, &fb_w, &fb_h);
mousePosScale.x = (float)fb_w / w; // Some screens e.g. Retina display have framebuffer size != from window size, and mouse inputs are given in window/screen coordinates.
mousePosScale.y = (float)fb_h / h;
ImGuiIO& io = ImGui::GetIO();
io.DisplaySize = ImVec2((float)fb_w, (float)fb_h); // Display size, in pixels. For clamping windows positions.
io.DeltaTime = 1.0f/60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our timestep is variable)
io.PixelCenterOffset = 0.0f; // Align OpenGL texels
io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
io.DeltaTime = 1.0f/60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our time step is variable)
io.PixelCenterOffset = 0.0f; // Align OpenGL texels
io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT;
io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT;
io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP;
@ -195,9 +179,6 @@ void InitImGui()
io.RenderDrawListsFn = ImImpl_RenderDrawLists;
io.SetClipboardTextFn = ImImpl_SetClipboardTextFn;
io.GetClipboardTextFn = ImImpl_GetClipboardTextFn;
#ifdef _MSC_VER
io.ImeSetInputScreenPosFn = ImImpl_ImeSetInputScreenPosFn;
#endif
// Load font texture
glGenTextures(1, &fontTex);
@ -215,7 +196,7 @@ void InitImGui()
IM_ASSERT(tex_data != NULL);
#else
// Custom font from filesystem
io.Font = new ImBitmapFont();
io.Font = new ImFont();
io.Font->LoadFromFile("../../extra_fonts/mplus-2m-medium_18.fnt");
IM_ASSERT(io.Font->IsLoaded());
@ -224,11 +205,11 @@ void InitImGui()
IM_ASSERT(tex_data != NULL);
// Automatically find white pixel from the texture we just loaded
// (io.FontTexUvForWhite needs to contains UV coordinates pointing to a white pixel in order to render solid objects)
// (io.Font->TexUvForWhite needs to contains UV coordinates pointing to a white pixel in order to render solid objects)
for (int tex_data_off = 0; tex_data_off < tex_x*tex_y; tex_data_off++)
if (((unsigned int*)tex_data)[tex_data_off] == 0xffffffff)
{
io.FontTexUvForWhite = ImVec2((float)(tex_data_off % tex_x)/(tex_x), (float)(tex_data_off / tex_x)/(tex_y));
io.Font->TexUvForWhite = ImVec2((float)(tex_data_off % tex_x)/(tex_x), (float)(tex_data_off / tex_x)/(tex_y));
break;
}
#endif
@ -241,7 +222,14 @@ void UpdateImGui()
{
ImGuiIO& io = ImGui::GetIO();
// Setup timestep
// Setup resolution (every frame to accommodate for window resizing)
int w, h;
int display_w, display_h;
glfwGetWindowSize(window, &w, &h);
glfwGetFramebufferSize(window, &display_w, &display_h);
io.DisplaySize = ImVec2((float)display_w, (float)display_h); // Display size, in pixels. For clamping windows positions.
// Setup time step
static double time = 0.0f;
const double current_time = glfwGetTime();
io.DeltaTime = (float)(current_time - time);
@ -251,7 +239,9 @@ void UpdateImGui()
// (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents())
double mouse_x, mouse_y;
glfwGetCursorPos(window, &mouse_x, &mouse_y);
io.MousePos = ImVec2((float)mouse_x * mousePosScale.x, (float)mouse_y * mousePosScale.y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
mouse_x *= (float)display_w / w; // Convert mouse coordinates to pixels
mouse_y *= (float)display_h / h;
io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
io.MouseDown[0] = mousePressed[0] || glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.
io.MouseDown[1] = mousePressed[1] || glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) != 0;
@ -269,7 +259,6 @@ int main(int argc, char** argv)
{
ImGuiIO& io = ImGui::GetIO();
mousePressed[0] = mousePressed[1] = false;
io.MouseWheel = 0;
glfwPollEvents();
UpdateImGui();
@ -285,7 +274,7 @@ int main(int argc, char** argv)
show_test_window ^= ImGui::Button("Test Window");
show_another_window ^= ImGui::Button("Another Window");
// Calculate and show framerate
// Calculate and show frame rate
static float ms_per_frame[120] = { 0 };
static int ms_per_frame_idx = 0;
static float ms_per_frame_accum = 0.0f;
@ -308,7 +297,7 @@ int main(int argc, char** argv)
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
if (show_test_window)
{
ImGui::SetNewWindowDefaultPos(ImVec2(650, 20)); // Normally user code doesn't need/want to call this, because positions are saved in .ini file. Here we just want to make the demo initial state a bit more friendly!
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCondition_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
}
@ -320,7 +309,9 @@ int main(int argc, char** argv)
glfwSwapBuffers(window);
}
// Cleanup
ImGui::Shutdown();
glfwTerminate();
return 0;
}

View File

@ -1,20 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl_example", "opengl_example.vcxproj", "{9CDA7840-B7A5-496D-A527-E95571496D18}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9CDA7840-B7A5-496D-A527-E95571496D18}.Debug|Win32.ActiveCfg = Debug|Win32
{9CDA7840-B7A5-496D-A527-E95571496D18}.Debug|Win32.Build.0 = Debug|Win32
{9CDA7840-B7A5-496D-A527-E95571496D18}.Release|Win32.ActiveCfg = Release|Win32
{9CDA7840-B7A5-496D-A527-E95571496D18}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -41,11 +41,11 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(SolutionDir)\glfw\include;$(SolutionDir)\glew\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)\glfw\include;$(ProjectDir)\glew\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\glfw\lib-msvc100;$(SolutionDir)\glew\lib\Release\Win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>$(ProjectDir)\glfw\lib-msvc100;$(ProjectDir)\glew\lib\Release\Win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>opengl32.lib;imm32.lib;glfw3.lib;glew32s.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>NotSet</SubSystem>
</Link>
@ -56,13 +56,13 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(SolutionDir)\glfw\include;$(SolutionDir)\glew\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)\glfw\include;$(ProjectDir)\glew\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(SolutionDir)\glfw\lib-msvc100;$(SolutionDir)\glew\lib\Release\Win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>$(ProjectDir)\glfw\lib-msvc100;$(ProjectDir)\glew\lib\Release\Win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>opengl32.lib;imm32.lib;glfw3.lib;glew32s.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>NotSet</SubSystem>
</Link>
@ -75,10 +75,7 @@
<ClInclude Include="..\..\imconfig.h" />
<ClInclude Include="..\..\imgui.h" />
<ClInclude Include="..\..\stb_textedit.h" />
<ClInclude Include="stb_image.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\LICENSE" />
<ClInclude Include="..\shared\stb_image.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View File

@ -18,9 +18,6 @@
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stb_image.h">
<Filter>sources</Filter>
</ClInclude>
<ClInclude Include="..\..\imconfig.h">
<Filter>imgui</Filter>
</ClInclude>
@ -30,10 +27,8 @@
<ClInclude Include="..\..\stb_textedit.h">
<Filter>imgui</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\LICENSE">
<Filter>imgui</Filter>
</None>
<ClInclude Include="..\shared\stb_image.h">
<Filter>sources</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -0,0 +1,3 @@
stb_image.h is used to load the PNG texture data by
opengl_example
directx11_example

View File

@ -39,7 +39,7 @@ Configure bmfont:
1. Load the .FNT data from 'fnt_data' (NB: this is done for you by default if you don't do anything)
ImGuiIO& io = ImGui::GetIO();
io.Font = new ImBitmapFont();
io.Font = new ImFont();
io.Font->LoadFromMemory(fnt_data, fnt_size);
2. Load the .PNG data from 'png_data' into a texture
@ -48,16 +48,16 @@ Configure bmfont:
(B) Use fonts from external files
You need to set io.FontTexUvForWhite to UV coordinates pointing to a white pixel in the texture.
You need to set io.Font->TexUvForWhite to UV coordinates pointing to a white pixel in the texture.
You can either locate a white pixel manually or use code at runtime to find or write one.
The OpenGL example include sample code to find a white pixel given an uncompressed 32-bits texture:
// Automatically find white pixel from the texture we just loaded
// (io.FontTexUvForWhite needs to contains UV coordinates pointing to a white pixel in order to render solid objects)
// (io.Font->TexUvForWhite needs to contains UV coordinates pointing to a white pixel in order to render solid objects)
for (int tex_data_off = 0; tex_data_off < tex_x*tex_y; tex_data_off++)
if (((unsigned int*)tex_data)[tex_data_off] == 0xffffffff)
{
io.FontTexUvForWhite = ImVec2((float)(tex_data_off % tex_x)/(tex_x), (float)(tex_data_off / tex_x)/(tex_y));
io.Font->TexUvForWhite = ImVec2((float)(tex_data_off % tex_x)/(tex_x), (float)(tex_data_off / tex_x)/(tex_y));
break;
}
@ -66,33 +66,33 @@ Configure bmfont:
ImGuiIO& io = ImGui::GetIO();
// proggy_clean_13 [default]
io.Font = new ImBitmapFont();
io.Font = new ImFont();
io.Font->LoadFromFile("proggy_clean_13.fnt");
IM_ASSERT(io.Font->IsLoaded());
io.FontTexUvForWhite = ImVec2(0.0f/256.0f,0.0f/128);
io.FontYOffset = +1;
io.Font->TexUvForWhite = ImVec2(0.0f/256.0f,0.0f/128);
io.Font->DisplayOffset = ImVec2(0.0f, +1.0f);
// proggy_small_12
io.Font = new ImBitmapFont();
io.Font = new ImFont();
io.Font->LoadFromFile("proggy_small_12.fnt");
IM_ASSERT(io.Font->IsLoaded());
io.FontTexUvForWhite = ImVec2(84.0f/256.0f,20.0f/64);
io.FontYOffset = +2;
io.Font->TexUvForWhite = ImVec2(84.0f/256.0f,20.0f/64);
io.Font->DisplayOffset = ImVec2(0.0f, +2.0f);
// proggy_small_14
io.Font = new ImBitmapFont();
io.Font = new ImFont();
io.Font->LoadFromFile("proggy_small_14.fnt");
IM_ASSERT(io.Font->IsLoaded());
io.FontTexUvForWhite = ImVec2(84.0f/256.0f,20.0f/64);
io.FontYOffset = +3;
io.Font->TexUvForWhite = ImVec2(84.0f/256.0f,20.0f/64);
io.Font->DisplayOffset = ImVec2(0.0f, +3.0f);
// courier_new_16
io.Font->LoadFromFile("courier_new_16.fnt");
io.FontTexUvForWhite = ImVec2(1.0f/256.0f,4.0f/128);
io.Font->TexUvForWhite = ImVec2(1.0f/256.0f,4.0f/128);
// courier_new_18
io.Font->LoadFromFile("courier_new_18.fnt");
io.FontTexUvForWhite = ImVec2(4.0f/256.0f,5.0f/256);
io.Font->TexUvForWhite = ImVec2(4.0f/256.0f,5.0f/256);
2. Load the matching .PNG data into a texture

View File

@ -20,6 +20,9 @@
//---- Include imgui_user.inl at the end of imgui.cpp so you can include code that extends ImGui using its private data/functions.
//#define IMGUI_INCLUDE_IMGUI_USER_INL
//---- Include imgui_user.h at the end of imgui.h
//#define IMGUI_INCLUDE_IMGUI_USER_H
//---- Define implicit cast operators to convert back<>forth from your math types and ImVec2/ImVec4.
/*
#define IM_VEC2_CLASS_EXTRA \
@ -39,6 +42,6 @@ namespace ImGui
{
void Value(const char* prefix, const MyVec2& v, const char* float_format = NULL);
void Value(const char* prefix, const MyVec4& v, const char* float_format = NULL);
};
}
*/

3419
imgui.cpp

File diff suppressed because it is too large Load Diff

635
imgui.h
View File

@ -1,4 +1,4 @@
// ImGui library v1.14
// ImGui library v1.20
// See .cpp file for commentary.
// See ImGui::ShowTestWindow() for sample code.
// Read 'Programmer guide' in .cpp for notes on how to setup ImGui in your codebase.
@ -7,7 +7,7 @@
#pragma once
struct ImDrawList;
struct ImBitmapFont;
struct ImFont;
struct ImGuiAabb;
struct ImGuiIO;
struct ImGuiStorage;
@ -19,21 +19,28 @@ struct ImGuiWindow;
#include <stdarg.h> // va_list
#include <stddef.h> // ptrdiff_t
#include <stdlib.h> // NULL, malloc
#include <string.h> // memset, memmove
#ifndef IM_ASSERT
#include <assert.h>
#define IM_ASSERT(_EXPR) assert(_EXPR)
#endif
#ifndef IMGUI_API
#define IMGUI_API
#endif
typedef unsigned int ImU32;
typedef unsigned short ImWchar;
typedef ImU32 ImGuiID;
typedef unsigned short ImWchar; // hold a character for display
typedef ImU32 ImGuiID; // hold widget unique ID
typedef int ImGuiCol; // enum ImGuiCol_
typedef int ImGuiStyleVar; // enum ImGuiStyleVar_
typedef int ImGuiKey; // enum ImGuiKey_
typedef int ImGuiColorEditMode; // enum ImGuiColorEditMode_
typedef int ImGuiWindowFlags; // enum ImGuiWindowFlags_
typedef int ImGuiSetCondition; // enum ImGuiSetCondition_
typedef int ImGuiInputTextFlags; // enum ImGuiInputTextFlags_
typedef ImBitmapFont* ImFont;
struct ImGuiTextEditCallbackData;
struct ImVec2
{
@ -60,10 +67,10 @@ struct ImVec4
namespace ImGui
{
// Proxy functions to access the MemAllocFn/MemFreeFn/MemReallocFn pointers in ImGui::GetIO(). The only reason they exist here is to allow ImVector<> to compile inline.
void* MemAlloc(size_t sz);
void MemFree(void* ptr);
void* MemRealloc(void* ptr, size_t sz);
};
IMGUI_API void* MemAlloc(size_t sz);
IMGUI_API void MemFree(void* ptr);
IMGUI_API void* MemRealloc(void* ptr, size_t sz);
}
// std::vector<> like class to avoid dragging dependencies (also: windows implementation of STL with debug enabled is absurdly slow, so let's bypass it so our code runs fast in debug).
// Use '#define ImVector std::vector' if you want to use the STL type or your own type.
@ -72,7 +79,7 @@ namespace ImGui
template<typename T>
class ImVector
{
private:
protected:
size_t Size;
size_t Capacity;
T* Data;
@ -111,175 +118,201 @@ public:
inline void push_back(const value_type& v) { if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); Data[Size++] = v; }
inline void pop_back() { IM_ASSERT(Size > 0); Size--; }
inline iterator erase(const_iterator it) { IM_ASSERT(it >= begin() && it < end()); const ptrdiff_t off = it - begin(); memmove(Data + off, Data + off + 1, (Size - off - 1) * sizeof(value_type)); Size--; return Data + off; }
inline void insert(const_iterator it, const value_type& v) { IM_ASSERT(it >= begin() && it <= end()); const ptrdiff_t off = it - begin(); if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); if (off < (int)Size) memmove(Data + off + 1, Data + off, (Size - off) * sizeof(value_type)); Data[off] = v; Size++; }
inline iterator erase(const_iterator it) { IM_ASSERT(it >= begin() && it < end()); const ptrdiff_t off = it - begin(); memmove(Data + off, Data + off + 1, (Size - (size_t)off - 1) * sizeof(value_type)); Size--; return Data + off; }
inline iterator insert(const_iterator it, const value_type& v) { IM_ASSERT(it >= begin() && it <= end()); const ptrdiff_t off = it - begin(); if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); if (off < (int)Size) memmove(Data + off + 1, Data + off, (Size - (size_t)off) * sizeof(value_type)); Data[off] = v; Size++; return Data + off; }
};
#endif // #ifndef ImVector
// Helpers at bottom of the file:
// - if (IMGUI_ONCE_UPON_A_FRAME) // Execute a block of code once per frame only
// - IMGUI_ONCE_UPON_A_FRAME // Execute a block of code once per frame only (convenient for creating UI within deep-nested code that runs multiple times)
// - struct ImGuiTextFilter // Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]"
// - struct ImGuiTextBuffer // Text buffer for logging/accumulating text
// - struct ImGuiStorage // Custom key value storage (if you need to alter open/close states manually)
// - struct ImDrawList // Draw command list
// - struct ImBitmapFont // Bitmap font loader
// - struct ImFont // Bitmap font loader
// ImGui End-user API
// In a namespace so that user can add extra functions (e.g. Value() helpers for your vector or common types)
namespace ImGui
{
// Main
ImGuiIO& GetIO();
ImGuiStyle& GetStyle();
void NewFrame();
void Render();
void Shutdown();
void ShowUserGuide();
void ShowStyleEditor(ImGuiStyle* ref = NULL);
void ShowTestWindow(bool* open = NULL);
IMGUI_API ImGuiIO& GetIO();
IMGUI_API ImGuiStyle& GetStyle();
IMGUI_API void NewFrame();
IMGUI_API void Render();
IMGUI_API void Shutdown();
IMGUI_API void ShowUserGuide();
IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL);
IMGUI_API void ShowTestWindow(bool* open = NULL);
// Window
bool Begin(const char* name = "Debug", bool* open = NULL, ImVec2 size = ImVec2(0,0), float fill_alpha = -1.0f, ImGuiWindowFlags flags = 0); // return false when window is collapsed, so you can early out in your code.
void End();
void BeginChild(const char* str_id, ImVec2 size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0);
void EndChild();
bool GetWindowIsFocused();
ImVec2 GetWindowSize();
float GetWindowWidth();
ImVec2 GetWindowPos(); // you should rarely need/care about the window position, but it can be useful if you want to use your own drawing.
void SetWindowPos(const ImVec2& pos); // set current window pos.
ImVec2 GetWindowContentRegionMin();
ImVec2 GetWindowContentRegionMax();
ImDrawList* GetWindowDrawList(); // get rendering command-list if you want to append your own draw primitives.
ImFont GetWindowFont();
float GetWindowFontSize();
void SetWindowFontScale(float scale); // per-window font scale. Adjust IO.FontBaseScale if you want to scale all windows together.
void SetScrollPosHere(); // adjust scrolling position to center into the current cursor position.
void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use 'offset' to access sub components of a multiple component widget.
void SetTreeStateStorage(ImGuiStorage* tree); // replace tree state storage with our own (if you want to manipulate it yourself, typically clear subsection of it).
ImGuiStorage* GetTreeStateStorage();
void PushItemWidth(float item_width);
void PopItemWidth();
float GetItemWidth();
void PushAllowKeyboardFocus(bool v); // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets.
void PopAllowKeyboardFocus();
void PushStyleColor(ImGuiCol idx, const ImVec4& col);
void PopStyleColor();
IMGUI_API bool Begin(const char* name = "Debug", bool* p_opened = NULL, ImVec2 size = ImVec2(0,0), float fill_alpha = -1.0f, ImGuiWindowFlags flags = 0);// return false when window is collapsed, so you can early out in your code. passing 'bool* p_opened' displays a Close button on the upper-right corner of the window, the pointed value will be set to false when the button is pressed.
IMGUI_API void End();
IMGUI_API void BeginChild(const char* str_id, ImVec2 size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // size==0.0f: use remaining window size, size<0.0f: use remaining window size minus abs(size). on each axis.
IMGUI_API void EndChild();
IMGUI_API bool GetWindowIsFocused();
IMGUI_API ImVec2 GetContentRegionMax(); // window or current column boundaries
IMGUI_API ImVec2 GetWindowContentRegionMin(); // window boundaries
IMGUI_API ImVec2 GetWindowContentRegionMax();
IMGUI_API ImDrawList* GetWindowDrawList(); // get rendering command-list if you want to append your own draw primitives.
IMGUI_API ImFont* GetWindowFont();
IMGUI_API float GetWindowFontSize();
IMGUI_API void SetWindowFontScale(float scale); // per-window font scale. Adjust IO.FontGlobalScale if you want to scale all windows.
IMGUI_API ImVec2 GetWindowPos(); // you should rarely need/care about the window position, but it can be useful if you want to do your own drawing.
IMGUI_API ImVec2 GetWindowSize(); // get current window position.
IMGUI_API float GetWindowWidth();
IMGUI_API bool GetWindowCollapsed();
IMGUI_API void SetWindowPos(const ImVec2& pos, ImGuiSetCondition cond = 0); // set current window position - call within Begin()/End().
IMGUI_API void SetWindowSize(const ImVec2& size, ImGuiSetCondition cond = 0); // set current window size. set to ImVec2(0,0) to force an auto-fit
IMGUI_API void SetWindowCollapsed(bool collapsed, ImGuiSetCondition cond = 0); // set current window collapsed state.
IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiSetCondition cond = 0); // set next window position - call before Begin().
IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiSetCondition cond = 0); // set next window size. set to ImVec2(0,0) to force an auto-fit
IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiSetCondition cond = 0); // set next window collapsed state.
IMGUI_API void SetScrollPosHere(); // adjust scrolling position to center into the current cursor position.
IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget.
IMGUI_API void SetStateStorage(ImGuiStorage* tree); // replace tree state storage with our own (if you want to manipulate it yourself, typically clear subsection of it).
IMGUI_API ImGuiStorage* GetStateStorage();
IMGUI_API void PushItemWidth(float item_width); // width of items for the common item+label case. default to ~2/3 of windows width.
IMGUI_API void PopItemWidth();
IMGUI_API float GetItemWidth();
IMGUI_API void PushAllowKeyboardFocus(bool v); // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets.
IMGUI_API void PopAllowKeyboardFocus();
IMGUI_API void PushStyleColor(ImGuiCol idx, const ImVec4& col);
IMGUI_API void PopStyleColor(int count = 1);
IMGUI_API void PushStyleVar(ImGuiStyleVar idx, float val);
IMGUI_API void PushStyleVar(ImGuiStyleVar idx, const ImVec2& val);
IMGUI_API void PopStyleVar(int count = 1);
IMGUI_API void PushTextWrapPos(float wrap_pos_x = 0.0f); // word-wrapping for Text*() commands. < 0.0f: no wrapping; 0.0f: wrap to end of window (or column); > 0.0f: wrap at 'wrap_pos_x' position in window local space.
IMGUI_API void PopTextWrapPos();
// Tooltip
void SetTooltip(const char* fmt, ...); // set tooltip under mouse-cursor, typically use with ImGui::IsHovered(). last call wins.
void SetTooltipV(const char* fmt, va_list args);
void BeginTooltip(); // use to create full-featured tooltip windows that aren't just text.
void EndTooltip();
IMGUI_API void SetTooltip(const char* fmt, ...); // set tooltip under mouse-cursor, typically use with ImGui::IsHovered(). last call wins.
IMGUI_API void SetTooltipV(const char* fmt, va_list args);
IMGUI_API void BeginTooltip(); // use to create full-featured tooltip windows that aren't just text.
IMGUI_API void EndTooltip();
// Layout
void Separator(); // horizontal line
void SameLine(int column_x = 0, int spacing_w = -1); // call between widgets to layout them horizontally
void Spacing();
void Columns(int count = 1, const char* id = NULL, bool border=true); // setup number of columns
void NextColumn(); // next column
float GetColumnOffset(int column_index = -1);
void SetColumnOffset(int column_index, float offset);
float GetColumnWidth(int column_index = -1);
ImVec2 GetCursorPos(); // cursor position is relative to window position
void SetCursorPos(const ImVec2& pos); // "
void SetCursorPosX(float x); // "
void SetCursorPosY(float y); // "
ImVec2 GetCursorScreenPos(); // cursor position in screen space
void AlignFirstTextHeightToWidgets(); // call once if the first item on the line is a Text() item and you want to vertically lower it to match subsequent (bigger) widgets.
float GetTextLineSpacing();
float GetTextLineHeight();
IMGUI_API void Separator(); // horizontal line
IMGUI_API void SameLine(int column_x = 0, int spacing_w = -1); // call between widgets to layout them horizontally
IMGUI_API void Spacing();
IMGUI_API void Columns(int count = 1, const char* id = NULL, bool border=true); // setup number of columns
IMGUI_API void NextColumn(); // next column
IMGUI_API float GetColumnOffset(int column_index = -1);
IMGUI_API void SetColumnOffset(int column_index, float offset);
IMGUI_API float GetColumnWidth(int column_index = -1);
IMGUI_API ImVec2 GetCursorPos(); // cursor position is relative to window position
IMGUI_API void SetCursorPos(const ImVec2& pos); // "
IMGUI_API void SetCursorPosX(float x); // "
IMGUI_API void SetCursorPosY(float y); // "
IMGUI_API ImVec2 GetCursorScreenPos(); // cursor position in screen space
IMGUI_API void AlignFirstTextHeightToWidgets(); // call once if the first item on the line is a Text() item and you want to vertically lower it to match subsequent (bigger) widgets.
IMGUI_API float GetTextLineSpacing();
IMGUI_API float GetTextLineHeight();
// ID scopes
void PushID(const char* str_id);
void PushID(const void* ptr_id);
void PushID(const int int_id);
void PopID();
// If you are creating repeated widgets in a loop you most likely want to push a unique identifier so ImGui can differentiate them.
// You can also use ## within your widget name to distinguish them from each others (see 'Programmer Guide')
IMGUI_API void PushID(const char* str_id); // push identifier into the ID stack. IDs are hash of the *entire* stack!
IMGUI_API void PushID(const void* ptr_id);
IMGUI_API void PushID(const int int_id);
IMGUI_API void PopID();
IMGUI_API ImGuiID GetID(const char* str_id); // calculate unique ID (hash of whole ID stack + given parameter). useful if you want to query into ImGuiStorage yourself. otherwise rarely needed.
IMGUI_API ImGuiID GetID(const void* ptr_id);
// Widgets
void Text(const char* fmt, ...);
void TextV(const char* fmt, va_list args);
void TextColored(const ImVec4& col, const char* fmt, ...); // shortcut to doing PushStyleColor(ImGuiCol_Text, col); Text(fmt, ...); PopStyleColor();
void TextColoredV(const ImVec4& col, const char* fmt, va_list args);
void TextUnformatted(const char* text, const char* text_end = NULL); // doesn't require null terminated string if 'text_end' is specified. no copy done to any bounded stack buffer, better for long chunks of text.
void LabelText(const char* label, const char* fmt, ...);
void LabelTextV(const char* label, const char* fmt, va_list args);
void BulletText(const char* fmt, ...);
void BulletTextV(const char* fmt, va_list args);
bool Button(const char* label, ImVec2 size = ImVec2(0,0), bool repeat_when_held = false);
bool SmallButton(const char* label);
bool CollapsingHeader(const char* label, const char* str_id = NULL, const bool display_frame = true, const bool default_open = false);
bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); // adjust display_format to decorate the value with a prefix or a suffix. Use power!=1.0 for logarithmic sliders.
bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
bool SliderAngle(const char* label, float* v, float v_degrees_min = -360.0f, float v_degrees_max = +360.0f); // *v in radians
bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* display_format = "%.0f");
void PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), size_t stride = sizeof(float));
void PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), size_t stride = sizeof(float));
bool Checkbox(const char* label, bool* v);
bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value);
bool RadioButton(const char* label, bool active);
bool RadioButton(const char* label, int* v, int v_button);
bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0);
bool InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0);
bool InputFloat2(const char* label, float v[2], int decimal_precision = -1);
bool InputFloat3(const char* label, float v[3], int decimal_precision = -1);
bool InputFloat4(const char* label, float v[4], int decimal_precision = -1);
bool InputInt(const char* label, int* v, int step = 1, int step_fast = 100, ImGuiInputTextFlags extra_flags = 0);
bool Combo(const char* label, int* current_item, const char** items, int items_count, int popup_height_items = 7);
bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int popup_height_items = 7); // Separate items with \0, end item-list with \0\0
bool Combo(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int popup_height_items = 7);
bool ColorButton(const ImVec4& col, bool small_height = false, bool outline_border = true);
bool ColorEdit3(const char* label, float col[3]);
bool ColorEdit4(const char* label, float col[4], bool show_alpha = true);
void ColorEditMode(ImGuiColorEditMode mode);
bool TreeNode(const char* str_label_id); // if returning 'true' the node is open and the user is responsible for calling TreePop
bool TreeNode(const char* str_id, const char* fmt, ...); // "
bool TreeNode(const void* ptr_id, const char* fmt, ...); // "
bool TreeNodeV(const char* str_id, const char* fmt, va_list args); // "
bool TreeNodeV(const void* ptr_id, const char* fmt, va_list args); // "
void TreePush(const char* str_id = NULL); // already called by TreeNode(), but you can call Push/Pop yourself for layouting purpose
void TreePush(const void* ptr_id = NULL); // "
void TreePop();
void OpenNextNode(bool open); // force open/close the next TreeNode or CollapsingHeader
IMGUI_API void Text(const char* fmt, ...);
IMGUI_API void TextV(const char* fmt, va_list args);
IMGUI_API void TextColored(const ImVec4& col, const char* fmt, ...); // shortcut for PushStyleColor(ImGuiCol_Text, col); Text(fmt, ...); PopStyleColor();
IMGUI_API void TextColoredV(const ImVec4& col, const char* fmt, va_list args);
IMGUI_API void TextWrapped(const char* fmt, ...); // shortcut for PushTextWrapPos(0.0f); Text(fmt, ...); PopTextWrapPos();
IMGUI_API void TextWrappedV(const char* fmt, va_list args);
IMGUI_API void TextUnformatted(const char* text, const char* text_end = NULL); // doesn't require null terminated string if 'text_end' is specified. no copy done to any bounded stack buffer, recommended for long chunks of text.
IMGUI_API void LabelText(const char* label, const char* fmt, ...); // display text+label aligned the same way as value+label widgets
IMGUI_API void LabelTextV(const char* label, const char* fmt, va_list args);
IMGUI_API void BulletText(const char* fmt, ...);
IMGUI_API void BulletTextV(const char* fmt, va_list args);
IMGUI_API bool Button(const char* label, ImVec2 size = ImVec2(0,0), bool repeat_when_held = false);
IMGUI_API bool SmallButton(const char* label);
IMGUI_API bool CollapsingHeader(const char* label, const char* str_id = NULL, const bool display_frame = true, const bool default_open = false);
IMGUI_API bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); // adjust display_format to decorate the value with a prefix or a suffix. Use power!=1.0 for logarithmic sliders.
IMGUI_API bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
IMGUI_API bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
IMGUI_API bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
IMGUI_API bool SliderAngle(const char* label, float* v, float v_degrees_min = -360.0f, float v_degrees_max = +360.0f); // *v in radians
IMGUI_API bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* display_format = "%.0f");
IMGUI_API bool SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* display_format = "%.0f");
IMGUI_API bool SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* display_format = "%.0f");
IMGUI_API bool SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* display_format = "%.0f");
IMGUI_API void PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), size_t stride = sizeof(float));
IMGUI_API void PlotLines(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0));
IMGUI_API void PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), size_t stride = sizeof(float));
IMGUI_API void PlotHistogram(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0));
IMGUI_API bool Checkbox(const char* label, bool* v);
IMGUI_API bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value);
IMGUI_API bool RadioButton(const char* label, bool active);
IMGUI_API bool RadioButton(const char* label, int* v, int v_button);
IMGUI_API bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, void (*callback)(ImGuiTextEditCallbackData*) = NULL, void* user_data = NULL);
IMGUI_API bool InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0);
IMGUI_API bool InputFloat2(const char* label, float v[2], int decimal_precision = -1);
IMGUI_API bool InputFloat3(const char* label, float v[3], int decimal_precision = -1);
IMGUI_API bool InputFloat4(const char* label, float v[4], int decimal_precision = -1);
IMGUI_API bool InputInt(const char* label, int* v, int step = 1, int step_fast = 100, ImGuiInputTextFlags extra_flags = 0);
IMGUI_API bool Combo(const char* label, int* current_item, const char** items, int items_count, int popup_height_items = 7);
IMGUI_API bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int popup_height_items = 7); // separate items with \0, end item-list with \0\0
IMGUI_API bool Combo(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int popup_height_items = 7);
IMGUI_API bool ColorButton(const ImVec4& col, bool small_height = false, bool outline_border = true);
IMGUI_API bool ColorEdit3(const char* label, float col[3]);
IMGUI_API bool ColorEdit4(const char* label, float col[4], bool show_alpha = true);
IMGUI_API void ColorEditMode(ImGuiColorEditMode mode);
IMGUI_API bool TreeNode(const char* str_label_id); // if returning 'true' the node is open and the user is responsible for calling TreePop
IMGUI_API bool TreeNode(const char* str_id, const char* fmt, ...); // "
IMGUI_API bool TreeNode(const void* ptr_id, const char* fmt, ...); // "
IMGUI_API bool TreeNodeV(const char* str_id, const char* fmt, va_list args); // "
IMGUI_API bool TreeNodeV(const void* ptr_id, const char* fmt, va_list args); // "
IMGUI_API void TreePush(const char* str_id = NULL); // already called by TreeNode(), but you can call Push/Pop yourself for layouting purpose
IMGUI_API void TreePush(const void* ptr_id = NULL); // "
IMGUI_API void TreePop();
IMGUI_API void OpenNextNode(bool open); // force open/close the next TreeNode or CollapsingHeader
// Value helper output "name: value"
// Freely declare your own in the ImGui namespace.
void Value(const char* prefix, bool b);
void Value(const char* prefix, int v);
void Value(const char* prefix, unsigned int v);
void Value(const char* prefix, float v, const char* float_format = NULL);
void Color(const char* prefix, const ImVec4& v);
void Color(const char* prefix, unsigned int v);
// Value() Helpers: output single value in "name: value" format. Tip: freely declare your own within the ImGui namespace!
IMGUI_API void Value(const char* prefix, bool b);
IMGUI_API void Value(const char* prefix, int v);
IMGUI_API void Value(const char* prefix, unsigned int v);
IMGUI_API void Value(const char* prefix, float v, const char* float_format = NULL);
IMGUI_API void Color(const char* prefix, const ImVec4& v);
IMGUI_API void Color(const char* prefix, unsigned int v);
// Logging
void LogButtons();
void LogToTTY(int max_depth = -1);
void LogToFile(int max_depth = -1, const char* filename = NULL);
void LogToClipboard(int max_depth = -1);
// Logging: All text output from your interface are redirected to tty/file/clipboard. Tree nodes are automatically opened.
IMGUI_API void LogToTTY(int max_depth = -1); // start logging to tty
IMGUI_API void LogToFile(int max_depth = -1, const char* filename = NULL); // start logging to file
IMGUI_API void LogToClipboard(int max_depth = -1); // start logging to OS clipboard
IMGUI_API void LogFinish(); // stop logging (close file, etc.)
IMGUI_API void LogButtons(); // helper to display buttons for logging to tty/file/clipboard
IMGUI_API void LogText(const char* fmt, ...); // pass text data straight to log (without being displayed)
// Utilities
void SetNewWindowDefaultPos(const ImVec2& pos); // set position of window that do
bool IsHovered(); // was the last item active area hovered by mouse?
ImVec2 GetItemBoxMin(); // get bounding box of last item
ImVec2 GetItemBoxMax(); // get bounding box of last item
bool IsClipped(const ImVec2& item_size); // to perform coarse clipping on user's side (as an optimisation)
bool IsKeyPressed(int key_index, bool repeat = true); // key_index into the keys_down[512] array, imgui doesn't know the semantic of each entry
bool IsMouseClicked(int button, bool repeat = false);
bool IsMouseDoubleClicked(int button);
bool IsMouseHoveringWindow(); // is mouse hovering current window ("window" in API names always refer to current window)
bool IsMouseHoveringAnyWindow(); // is mouse hovering any active imgui window
bool IsMouseHoveringBox(const ImVec2& box_min, const ImVec2& box_max); // is mouse hovering given bounding box
bool IsPosHoveringAnyWindow(const ImVec2& pos); // is given position hovering any active imgui window
ImVec2 GetMousePos(); // shortcut to ImGui::GetIO().MousePos provided by user, to be consistent with other calls
float GetTime();
int GetFrameCount();
const char* GetStyleColorName(ImGuiCol idx);
void GetDefaultFontData(const void** fnt_data, unsigned int* fnt_size, const void** png_data, unsigned int* png_size);
ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, const bool hide_text_after_hash = true);
IMGUI_API bool IsItemHovered(); // was the last item active area hovered by mouse?
IMGUI_API bool IsItemFocused(); // was the last item focused for keyboard input?
IMGUI_API ImVec2 GetItemBoxMin(); // get bounding box of last item
IMGUI_API ImVec2 GetItemBoxMax(); // get bounding box of last item
IMGUI_API bool IsClipped(const ImVec2& item_size); // to perform coarse clipping on user's side (as an optimization)
IMGUI_API bool IsKeyPressed(int key_index, bool repeat = true); // key_index into the keys_down[512] array, imgui doesn't know the semantic of each entry
IMGUI_API bool IsMouseClicked(int button, bool repeat = false);
IMGUI_API bool IsMouseDoubleClicked(int button);
IMGUI_API bool IsMouseHoveringWindow(); // is mouse hovering current window ("window" in API names always refer to current window)
IMGUI_API bool IsMouseHoveringAnyWindow(); // is mouse hovering any active imgui window
IMGUI_API bool IsMouseHoveringBox(const ImVec2& box_min, const ImVec2& box_max); // is mouse hovering given bounding box
IMGUI_API bool IsPosHoveringAnyWindow(const ImVec2& pos); // is given position hovering any active imgui window
IMGUI_API ImVec2 GetMousePos(); // shortcut to ImGui::GetIO().MousePos provided by user, to be consistent with other calls
IMGUI_API float GetTime();
IMGUI_API int GetFrameCount();
IMGUI_API const char* GetStyleColName(ImGuiCol idx);
IMGUI_API void GetDefaultFontData(const void** fnt_data, unsigned int* fnt_size, const void** png_data, unsigned int* png_size);
IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f);
}; // namespace ImGui
} // namespace ImGui
// Flags for ImGui::Begin()
enum ImGuiWindowFlags_
@ -290,11 +323,14 @@ enum ImGuiWindowFlags_
ImGuiWindowFlags_NoResize = 1 << 2,
ImGuiWindowFlags_NoMove = 1 << 3,
ImGuiWindowFlags_NoScrollbar = 1 << 4,
ImGuiWindowFlags_ChildWindow = 1 << 5, // For internal use by BeginChild()
ImGuiWindowFlags_ChildWindowAutoFitX = 1 << 6, // For internal use by BeginChild()
ImGuiWindowFlags_ChildWindowAutoFitY = 1 << 7, // For internal use by BeginChild()
ImGuiWindowFlags_ComboBox = 1 << 8, // For internal use by ComboBox()
ImGuiWindowFlags_Tooltip = 1 << 9, // For internal use by Render() when using Tooltip
ImGuiWindowFlags_NoScrollWithMouse = 1 << 5,
ImGuiWindowFlags_AlwaysAutoResize = 1 << 6,
ImGuiWindowFlags_NoSavedSettings = 1 << 7, // Never load/save settings in .ini file
ImGuiWindowFlags_ChildWindow = 1 << 8, // For internal use by BeginChild()
ImGuiWindowFlags_ChildWindowAutoFitX = 1 << 9, // For internal use by BeginChild()
ImGuiWindowFlags_ChildWindowAutoFitY = 1 << 10, // For internal use by BeginChild()
ImGuiWindowFlags_ComboBox = 1 << 11, // For internal use by ComboBox()
ImGuiWindowFlags_Tooltip = 1 << 12 // For internal use by Render() when using Tooltip
};
// Flags for ImGui::InputText()
@ -305,7 +341,10 @@ enum ImGuiInputTextFlags_
ImGuiInputTextFlags_CharsHexadecimal = 1 << 1, // Allow 0123456789ABCDEFabcdef
ImGuiInputTextFlags_AutoSelectAll = 1 << 2, // Select entire text when first taking focus
ImGuiInputTextFlags_EnterReturnsTrue = 1 << 3, // Return 'true' when Enter is pressed (as opposed to when the value was modified)
//ImGuiInputTextFlags_AlignCenter = 1 << 3,
ImGuiInputTextFlags_CallbackCompletion = 1 << 4, // Call user function on pressing TAB (for completion handling)
ImGuiInputTextFlags_CallbackHistory = 1 << 5, // Call user function on pressing Up/Down arrows (for history handling)
ImGuiInputTextFlags_CallbackAlways = 1 << 6 // Call user function every time
//ImGuiInputTextFlags_AlignCenter = 1 << 6,
};
// User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array
@ -328,9 +367,10 @@ enum ImGuiKey_
ImGuiKey_X, // for CTRL+X: cut
ImGuiKey_Y, // for CTRL+Y: redo
ImGuiKey_Z, // for CTRL+Z: undo
ImGuiKey_COUNT,
ImGuiKey_COUNT
};
// Enumeration for PushStyleColor() / PopStyleColor()
enum ImGuiCol_
{
ImGuiCol_Text,
@ -347,6 +387,7 @@ enum ImGuiCol_
ImGuiCol_ComboBg,
ImGuiCol_CheckHovered,
ImGuiCol_CheckActive,
ImGuiCol_CheckMark,
ImGuiCol_SliderGrab,
ImGuiCol_SliderGrabActive,
ImGuiCol_Button,
@ -370,15 +411,38 @@ enum ImGuiCol_
ImGuiCol_PlotHistogramHovered,
ImGuiCol_TextSelectedBg,
ImGuiCol_TooltipBg,
ImGuiCol_COUNT,
ImGuiCol_COUNT
};
// Enumeration for PushStyleVar() / PopStyleVar()
// NB: the enum only refers to fields of ImGuiStyle() which makes sense to be pushed/poped in UI code. Feel free to add others.
enum ImGuiStyleVar_
{
ImGuiStyleVar_Alpha, // float
ImGuiStyleVar_WindowPadding, // ImVec2
ImGuiStyleVar_WindowRounding, // float
ImGuiStyleVar_FramePadding, // ImVec2
ImGuiStyleVar_ItemSpacing, // ImVec2
ImGuiStyleVar_ItemInnerSpacing, // ImVec2
ImGuiStyleVar_TreeNodeSpacing, // float
};
// Enumeration for ColorEditMode()
enum ImGuiColorEditMode_
{
ImGuiColorEditMode_UserSelect = -1,
ImGuiColorEditMode_RGB = 0,
ImGuiColorEditMode_HSV = 1,
ImGuiColorEditMode_HEX = 2,
ImGuiColorEditMode_HEX = 2
};
// Condition flags for ImGui::SetWindow***() and SetNextWindow***() functions
// Those functions treat 0 as a shortcut to ImGuiSetCondition_Always
enum ImGuiSetCondition_
{
ImGuiSetCondition_Always = 1 << 0, // Set the variable
ImGuiSetCondition_FirstUseThisSession = 1 << 1, // Only set the variable on the first call for this window (once per session)
ImGuiSetCondition_FirstUseEver = 1 << 2, // Only set the variable if the window doesn't exist in the .ini file
};
struct ImGuiStyle
@ -386,19 +450,19 @@ struct ImGuiStyle
float Alpha; // Global alpha applies to everything in ImGui
ImVec2 WindowPadding; // Padding within a window
ImVec2 WindowMinSize; // Minimum window size
float WindowRounding; // Radius of window corners rounding. Set to 0.0f to have rectangular windows
ImVec2 FramePadding; // Padding within a framed rectangle (used by most widgets)
ImVec2 ItemSpacing; // Horizontal and vertical spacing between widgets/lines
ImVec2 ItemInnerSpacing; // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label)
ImVec2 TouchExtraPadding; // Expand bounding box for touch-based system where touch position is not accurate enough (unnecessary for mouse inputs). Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget running. So dont grow this too much!
ImVec2 AutoFitPadding; // Extra space after auto-fit (double-clicking on resize grip)
float WindowFillAlphaDefault; // Default alpha of window background, if not specified in ImGui::Begin()
float WindowRounding; // Radius of window corners rounding. Set to 0.0f to have rectangular windows
float TreeNodeSpacing; // Horizontal spacing when entering a tree node
float ColumnsMinSpacing; // Minimum horizontal spacing between two columns
float ScrollBarWidth; // Width of the vertical scroll bar
ImVec4 Colors[ImGuiCol_COUNT];
ImGuiStyle();
IMGUI_API ImGuiStyle();
};
// This is where your app communicate with ImGui. Call ImGui::GetIO() to access.
@ -411,18 +475,15 @@ struct ImGuiIO
ImVec2 DisplaySize; // <unset> // Display size, in pixels. For clamping windows positions.
float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds.
float IniSavingRate; // = 5.0f // Maximum time between saving .ini file, in seconds. Set to a negative value to disable .ini saving.
const char* IniFilename; // = "imgui.ini" // Absolute path to .ini file.
const char* LogFilename; // = "imgui_log.txt" // Absolute path to .log file.
float IniSavingRate; // = 5.0f // Maximum time between saving .ini file, in seconds.
const char* IniFilename; // = "imgui.ini" // Path to .ini file. NULL to disable .ini saving.
const char* LogFilename; // = "imgui_log.txt" // Path to .log file (default parameter to ImGui::LogToFile when no file is specified).
float MouseDoubleClickTime; // = 0.30f // Time for a double-click, in seconds.
float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels.
int KeyMap[ImGuiKey_COUNT]; // <unset> // Map of indices into the KeysDown[512] entries array
ImFont Font; // <auto> // Gets passed to text functions. Typedef ImFont to the type you want (ImBitmapFont* or your own font).
float FontYOffset; // = 0.0f // Offset font rendering by xx pixels in Y axis.
ImVec2 FontTexUvForWhite; // = (0.0f,0.0f) // Font texture must have a white pixel at this UV coordinate. Adjust if you are using custom texture.
float FontBaseScale; // = 1.0f // Base font scale, multiplied by the per-window font scale which you can adjust with SetFontScale()
bool FontAllowUserScaling; // = false // Set to allow scaling text with CTRL+Wheel.
ImWchar FontFallbackGlyph; // = '?' // Replacement glyph is one isn't found.
ImFont* Font; // <auto> // Font (also see 'Settings' fields inside ImFont structure for details)
float FontGlobalScale; // = 1.0f // Global scale all fonts
bool FontAllowUserScaling; // = false // Allow user scaling text of individual window with CTRL+Wheel.
float PixelCenterOffset; // = 0.0f // Try to set to 0.5f or 0.375f if rendering is blurry
void* UserData; // = NULL // Store your own data for retrieval by callbacks.
@ -445,7 +506,7 @@ struct ImGuiIO
void* (*MemReallocFn)(void* ptr, size_t sz);
void (*MemFreeFn)(void* ptr);
// Optional: notify OS Input Method Editor of text input position (e.g. when using Japanese/Chinese inputs, otherwise this isn't needed)
// Optional: notify OS Input Method Editor of the screen position of your cursor for text input position (e.g. when using Japanese/Chinese inputs in Windows)
void (*ImeSetInputScreenPosFn)(int x, int y);
//------------------------------------------------------------------
@ -454,14 +515,14 @@ struct ImGuiIO
ImVec2 MousePos; // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
bool MouseDown[5]; // Mouse buttons. ImGui itself only uses button 0 (left button) but you can use others as storage for convenience.
int MouseWheel; // Mouse wheel: -1,0,+1
float MouseWheel; // Mouse wheel: 1 unit scrolls about 5 lines text.
bool KeyCtrl; // Keyboard modifier pressed: Control
bool KeyShift; // Keyboard modifier pressed: Shift
bool KeysDown[512]; // Keyboard keys that are pressed (in whatever order user naturally has access to keyboard data)
ImWchar InputCharacters[16+1]; // List of characters input (translated by user from keypress+keyboard state). Fill using AddInputCharacter() helper.
// Function
void AddInputCharacter(ImWchar); // Helper to add a new character into InputCharacters[]
IMGUI_API void AddInputCharacter(ImWchar c); // Helper to add a new character into InputCharacters[]
//------------------------------------------------------------------
// Output - Retrieve after calling NewFrame(), you can use them to discard inputs or hide them from the rest of your application
@ -483,7 +544,7 @@ struct ImGuiIO
float MouseDownTime[5];
float KeysDownTime[512];
ImGuiIO();
IMGUI_API ImGuiIO();
};
//-----------------------------------------------------------------------------
@ -491,15 +552,19 @@ struct ImGuiIO
//-----------------------------------------------------------------------------
// Helper: execute a block of code once a frame only
// Usage: if (IMGUI_ONCE_UPON_A_FRAME) {/*do something once a frame*/)
#define IMGUI_ONCE_UPON_A_FRAME static ImGuiOncePerFrame im = ImGuiOncePerFrame()
struct ImGuiOncePerFrame
// Convenient if you want to quickly create an UI within deep-nested code that runs multiple times every frame.
// Usage:
// IMGUI_ONCE_UPON_A_FRAME
// {
// // code block will be executed one per frame
// }
// Attention! the macro expands into 2 statement so make sure you don't use it within e.g. an if() statement without curly braces.
#define IMGUI_ONCE_UPON_A_FRAME static ImGuiOnceUponAFrame imgui_oaf##__LINE__; if (imgui_oaf##__LINE__)
struct ImGuiOnceUponAFrame
{
ImGuiOncePerFrame() : LastFrame(-1) {}
operator bool() const { return TryIsNewFrame(); }
private:
mutable int LastFrame;
bool TryIsNewFrame() const { const int current_frame = ImGui::GetFrameCount(); if (LastFrame == current_frame) return false; LastFrame = current_frame; return true; }
ImGuiOnceUponAFrame() { RefFrame = -1; }
mutable int RefFrame;
operator bool() const { const int current_frame = ImGui::GetFrameCount(); if (RefFrame == current_frame) return false; RefFrame = current_frame; return true; }
};
// Helper: Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]"
@ -518,7 +583,7 @@ struct ImGuiTextFilter
char front() const { return *b; }
static bool isblank(char c) { return c == ' ' || c == '\t'; }
void trim_blanks() { while (b < e && isblank(*b)) b++; while (e > b && isblank(*(e-1))) e--; }
void split(char separator, ImVector<TextRange>& out);
IMGUI_API void split(char separator, ImVector<TextRange>& out);
};
char InputBuf[256];
@ -530,7 +595,7 @@ struct ImGuiTextFilter
void Draw(const char* label = "Filter (inc,-exc)", float width = -1.0f); // Helper calling InputText+Build
bool PassFilter(const char* val) const;
bool IsActive() const { return !Filters.empty(); }
void Build();
IMGUI_API void Build();
};
// Helper: Text buffer for logging/accumulating text
@ -539,31 +604,67 @@ struct ImGuiTextBuffer
ImVector<char> Buf;
ImGuiTextBuffer() { Buf.push_back(0); }
const char* begin() const { return Buf.begin(); }
const char* end() const { return Buf.end()-1; }
~ImGuiTextBuffer() { clear(); }
const char* begin() const { return &Buf.front(); }
const char* end() const { return &Buf.back(); } // Buf is zero-terminated, so end() will point on the zero-terminator
size_t size() const { return Buf.size()-1; }
bool empty() { return Buf.empty(); }
void clear() { Buf.clear(); Buf.push_back(0); }
void append(const char* fmt, ...);
IMGUI_API void append(const char* fmt, ...);
IMGUI_API void appendv(const char* fmt, va_list args);
};
// Helper: Key->value storage
// - Store collapse state for a tree
// - Store color edit options, etc.
// - Store collapse state for a tree (Int 0/1)
// - Store color edit options (Int using values in ImGuiColorEditMode enum).
// - Custom user storage for temporary values.
// Typically you don't have to worry about this since a storage is held within each Window.
// Declare your own storage if you want to manipulate the open/close state of a particular sub-tree in your interface.
// Declare your own storage if:
// - You want to manipulate the open/close state of a particular sub-tree in your interface (tree node uses Int 0/1 to store their state).
// - You want to store custom debug data easily without adding or editing structures in your code.
struct ImGuiStorage
{
struct Pair { ImU32 key; int val; };
ImVector<Pair> Data;
struct Pair
{
ImGuiID key;
union { int val_i; float val_f; };
Pair(ImGuiID _key, int _val_i) { key = _key; val_i = _val_i; }
Pair(ImGuiID _key, float _val_f) { key = _key; val_f = _val_f; }
};
ImVector<Pair> Data;
void Clear();
int GetInt(ImU32 key, int default_val = 0);
void SetInt(ImU32 key, int val);
void SetAllInt(int val);
// - Get***() functions find pair, never add/allocate. Pairs are sorted so a query is O(log N)
// - Set***() functions find pair, insertion on demand if missing.
// - Get***Ptr() functions find pair, insertion on demand if missing, return pointer. Useful if you intend to do Get+Set.
// A typical use case where this is very convenient:
// float* pvar = ImGui::GetIntPtr(key); ImGui::SliderInt("var", pvar, 0, 100); some_var += *pvar;
// - Sorted insertion is costly but should amortize. A typical frame shouldn't need to insert any new pair.
IMGUI_API void Clear();
IMGUI_API int GetInt(ImGuiID key, int default_val = 0) const;
IMGUI_API void SetInt(ImGuiID key, int val);
IMGUI_API int* GetIntPtr(ImGuiID key, int default_val = 0);
IMGUI_API float GetFloat(ImGuiID key, float default_val = 0.0f) const;
IMGUI_API void SetFloat(ImGuiID key, float val);
IMGUI_API float* GetFloatPtr(ImGuiID key, float default_val = 0);
IMGUI_API void SetAllInt(int val); // Use on your own storage if you know only integer are being stored.
};
int* Find(ImU32 key);
void Insert(ImU32 key, int val);
// Shared state of InputText(), passed to callback when a ImGuiInputTextFlags_Callback* flag is used.
struct ImGuiTextEditCallbackData
{
ImGuiKey EventKey; // Key pressed (Up/Down/TAB) // Read-only
char* Buf; // Current text // Read-write (pointed data only)
size_t BufSize; // // Read-only
bool BufDirty; // Set if you modify Buf directly // Write
ImGuiInputTextFlags Flags; // What user passed to InputText() // Read-only
int CursorPos; // // Read-write
int SelectionStart; // // Read-write (== to SelectionEnd when no selection)
int SelectionEnd; // // Read-write
void* UserData; // What user passed to InputText()
// NB: calling those function loses selection.
void DeleteChars(int pos, int bytes_count);
void InsertChars(int pos, const char* text, const char* text_end = NULL);
};
//-----------------------------------------------------------------------------
@ -577,16 +678,24 @@ struct ImDrawCmd
ImVec4 clip_rect;
};
#ifndef IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT
// Default vertex layout
struct ImDrawVert
{
ImVec2 pos;
ImVec2 uv;
ImU32 col;
};
#else
// You can change the vertex format layout by defining IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT in imconfig.h
// The code expect ImVec2 pos (8 bytes), ImVec2 uv (8 bytes), ImU32 col (4 bytes), but you can re-order them or add other fields as needed to simplify integration in your engine.
// The type has to be described by the #define (you can either declare the struct or use a typedef)
IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT;
#endif
// Draw command list
// This is the low-level list of polygon that ImGui:: functions are filling. At the end of the frame, all command lists are passed to your ImGuiIO::RenderDrawListFn function for rendering.
// Each ImGui window contains its own ImDrawList.
// This is the low-level list of polygon that ImGui:: functions are creating. At the end of the frame, all command lists are passed to your ImGuiIO::RenderDrawListFn function for rendering.
// At the moment, each ImGui window contains its own ImDrawList but they could potentially be merged.
// If you want to add custom rendering within a window, you can use ImGui::GetWindowDrawList() to access the current draw list and add your own primitives.
// You can interleave normal ImGui:: calls and adding primitives to the current draw list.
// Note that this only gives you access to rendering polygons. If your intent is to create custom widgets and the publicly exposed functions/data aren't sufficient, you can add code in imgui_user.inl
@ -602,34 +711,76 @@ struct ImDrawList
ImDrawList() { Clear(); }
void Clear();
void PushClipRect(const ImVec4& clip_rect);
void PopClipRect();
void ReserveVertices(unsigned int vtx_count);
void AddVtx(const ImVec2& pos, ImU32 col);
void AddVtxLine(const ImVec2& a, const ImVec2& b, ImU32 col);
IMGUI_API void Clear();
IMGUI_API void PushClipRect(const ImVec4& clip_rect);
IMGUI_API void PopClipRect();
IMGUI_API void ReserveVertices(unsigned int vtx_count);
IMGUI_API void AddVtx(const ImVec2& pos, ImU32 col);
IMGUI_API void AddVtxLine(const ImVec2& a, const ImVec2& b, ImU32 col);
// Primitives
void AddLine(const ImVec2& a, const ImVec2& b, ImU32 col);
void AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners=0x0F);
void AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners=0x0F);
void AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col);
void AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12);
void AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12);
void AddArc(const ImVec2& center, float rad, ImU32 col, int a_min, int a_max, bool tris=false, const ImVec2& third_point_offset = ImVec2(0,0));
void AddText(ImFont font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end);
// Primitives
IMGUI_API void AddLine(const ImVec2& a, const ImVec2& b, ImU32 col);
IMGUI_API void AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners=0x0F);
IMGUI_API void AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners=0x0F);
IMGUI_API void AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col);
IMGUI_API void AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12);
IMGUI_API void AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12);
IMGUI_API void AddArc(const ImVec2& center, float rad, ImU32 col, int a_min, int a_max, bool tris = false, const ImVec2& third_point_offset = ImVec2(0,0));
IMGUI_API void AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f);
};
// Optional bitmap font data loader & renderer into vertices
// #define ImFont to ImBitmapFont to use
// Bitmap font data loader & renderer into vertices
// Using the .fnt format exported by BMFont
// - tool: http://www.angelcode.com/products/bmfont
// - file-format: http://www.angelcode.com/products/bmfont/doc/file_format.html
// Assume valid file data (won't handle invalid/malicious data)
// Handle a subset of parameters.
// - kerning pair are not supported (because ImGui code does per-character CalcTextSize calls, need to turn it into something more stateful to allow kerning)
struct ImBitmapFont
// Handle a subset of the options, namely:
// - kerning pair are not supported (because some ImGui code does per-character CalcTextSize calls, need to turn it into something more state-ful to allow for kerning)
struct ImFont
{
struct FntInfo;
struct FntCommon;
struct FntGlyph;
struct FntKerning;
// Settings
float Scale; // = 1.0f // Base font scale, multiplied by the per-window font scale which you can adjust with SetFontScale()
ImVec2 DisplayOffset; // = (0.0f,0.0f) // Offset font rendering by xx pixels
ImVec2 TexUvForWhite; // = (0.0f,0.0f) // Font texture must have a white pixel at this UV coordinate. Adjust if you are using custom texture.
ImWchar FallbackChar; // = '?' // Replacement glyph is one isn't found.
// Data
unsigned char* Data; // Raw data, content of .fnt file
size_t DataSize; //
bool DataOwned; //
const FntInfo* Info; // (point into raw data)
const FntCommon* Common; // (point into raw data)
const FntGlyph* Glyphs; // (point into raw data)
size_t GlyphsCount; //
const FntKerning* Kerning; // (point into raw data) - NB: kerning is unsupported
size_t KerningCount; //
ImVector<const char*> Filenames; // (point into raw data)
ImVector<int> IndexLookup; // (built)
const FntGlyph* FallbackGlyph; // == FindGlyph(FontFallbackChar)
IMGUI_API ImFont();
IMGUI_API ~ImFont() { Clear(); }
IMGUI_API bool LoadFromMemory(const void* data, size_t data_size);
IMGUI_API bool LoadFromFile(const char* filename);
IMGUI_API void Clear();
IMGUI_API void BuildLookupTable();
IMGUI_API const FntGlyph* FindGlyph(unsigned short c) const;
IMGUI_API bool IsLoaded() const { return Info != NULL && Common != NULL && Glyphs != NULL; }
// 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable.
// 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable.
IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL) const; // utf8
IMGUI_API ImVec2 CalcTextSizeW(float size, float max_width, const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL) const; // wchar
IMGUI_API void RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, ImDrawVert*& out_vertices, float wrap_width = 0.0f) const;
IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const;
#pragma pack(push, 1)
struct FntInfo
{
@ -639,15 +790,13 @@ struct ImBitmapFont
unsigned short StretchH;
unsigned char AA;
unsigned char PaddingUp, PaddingRight, PaddingDown, PaddingLeft;
unsigned char SpacingHoriz, SpacingVert;
unsigned char Outline;
unsigned char SpacingHoriz, SpacingVert, Outline;
//char FontName[];
};
struct FntCommon
{
unsigned short LineHeight;
unsigned short Base;
unsigned short LineHeight, Base;
unsigned short ScaleW, ScaleH;
unsigned short Pages;
unsigned char BitField;
@ -657,8 +806,7 @@ struct ImBitmapFont
struct FntGlyph
{
unsigned int Id;
unsigned short X, Y;
unsigned short Width, Height;
unsigned short X, Y, Width, Height;
signed short XOffset, YOffset;
signed short XAdvance;
unsigned char Page;
@ -672,32 +820,11 @@ struct ImBitmapFont
signed short Amount;
};
#pragma pack(pop)
unsigned char* Data; // Raw data, content of .fnt file
size_t DataSize; //
bool DataOwned; //
const FntInfo* Info; // (point into raw data)
const FntCommon* Common; // (point into raw data)
const FntGlyph* Glyphs; // (point into raw data)
size_t GlyphsCount; //
const FntKerning* Kerning; // (point into raw data)
size_t KerningCount; //
int TabCount; // FIXME: mishandled (add fixed amount instead of aligning to column)
ImVector<const char*> Filenames; // (point into raw data)
ImVector<int> IndexLookup; // (built)
ImBitmapFont();
~ImBitmapFont() { Clear(); }
bool LoadFromMemory(const void* data, size_t data_size);
bool LoadFromFile(const char* filename);
void Clear();
void BuildLookupTable();
const FntGlyph * FindGlyph(unsigned short c) const;
float GetFontSize() const { return (float)Info->FontSize; }
bool IsLoaded() const { return Info != NULL && Common != NULL && Glyphs != NULL; }
ImVec2 CalcTextSizeA(float size, float max_width, const char* text_begin, const char* text_end, const char** remaining = NULL) const; // utf8
ImVec2 CalcTextSizeW(float size, float max_width, const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL) const; // wchar
void RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, ImDrawVert*& out_vertices) const;
};
//---- Include imgui_user.h at the end of imgui.h
//---- So you can include code that extends ImGui using any of the types declared above.
//---- (also convenient for user to only explicitly include vanilla imgui.h)
#ifdef IMGUI_INCLUDE_IMGUI_USER_H
#include "imgui_user.h"
#endif

View File

@ -1008,13 +1008,13 @@ static void stb_textedit_discard_undo(StbUndoState *state)
int n = state->undo_rec[0].insert_length, i;
// delete n characters from all other records
state->undo_char_point = state->undo_char_point - (short) n; // vsnet05
memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE)));
memmove(state->undo_char, state->undo_char + n, (size_t) ((size_t)state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE)));
for (i=0; i < state->undo_point; ++i)
if (state->undo_rec[i].char_storage >= 0)
state->undo_rec[i].char_storage = state->undo_rec[i].char_storage - (short) n; // vsnet05 // @OPTIMIZE: get rid of char_storage and infer it
}
--state->undo_point;
memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0])));
memmove(state->undo_rec, state->undo_rec+1, (size_t) ((size_t)state->undo_point*sizeof(state->undo_rec[0])));
}
}
@ -1032,13 +1032,13 @@ static void stb_textedit_discard_redo(StbUndoState *state)
int n = state->undo_rec[k].insert_length, i;
// delete n characters from all other records
state->redo_char_point = state->redo_char_point + (short) n; // vsnet05
memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE)));
memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((size_t)(STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE)));
for (i=state->redo_point; i < k; ++i)
if (state->undo_rec[i].char_storage >= 0)
state->undo_rec[i].char_storage = state->undo_rec[i].char_storage + (short) n; // vsnet05
}
++state->redo_point;
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])));
memmove(state->undo_rec + state->redo_point-1, state->undo_rec + state->redo_point, (size_t) ((size_t)(STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0])));
}
}

BIN
web/performance_01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB