Compare commits

..

155 Commits
v1.10 ... v1.17

Author SHA1 Message Date
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
1037bacc4b Version number 2014-10-25 11:15:28 +01:00
89a412690c Added comment on return value of Begin() 2014-10-25 11:01:20 +01:00
af37fb1ee7 Added GetWindowFont(), GetWindowFontSize() + comments following user's feedback 2014-10-25 11:00:24 +01:00
9f05a2bb16 Fixed unlikely buffer overrun in InputCharacters (thanks Daniel Collin) 2014-10-07 12:15:59 +01:00
48a944813c Moved UserData 2014-10-05 09:11:02 +01:00
1d9a4748de Added a UserData void *pointer so that the callback functions can access user state
"Just in case a project has adverse reactions to adding globals or
statics in their own code."
2014-10-05 09:08:57 +01:00
36212b9ad9 Merge pull request #56 from seanmiddleditch/master
64-bit fixes
2014-10-04 18:54:43 +02:00
bebadb9012 64-bit fixes
`int` values are not the same thing as `size_t` nor `ptrdiff_t`. Convert incorrect uses of `int` to more appropriate types.

Fixes warnings for 64-bit compilations.
2014-10-03 20:24:04 -07:00
530e746daa Renamed IMGUI_INCLUDE_IMGUI_USER_CPP to IMGUI_INCLUDE_IMGUI_USER_INL (more IDE friendly) 2014-10-02 11:56:40 +01:00
ce481ec702 SetKeyboardFocusHere() allow for an offset to access sub components + comments 2014-09-30 12:31:35 +01:00
f1ea630dd0 SetKeyboardFocusHere() sets focus on next widget instead of previous + works on tabbing-disabled widgets 2014-09-30 12:22:58 +01:00
ffc8264e9d Added SetKeyboardFocusHere() to set focus from code. Fixed tabbing through tab-disabled fields. 2014-09-30 11:57:37 +01:00
ec625b7c49 OpenGL/DirextX examples: comments and tweaks. 2014-09-30 10:09:44 +01:00
f86286548e OpenGL example: Tentative fix for missed tap-to-click events on MacBook trackpad 2014-09-30 09:58:02 +01:00
7751ce0a69 Merge pull request #51 from TS-RTX1911/master
opengl_example shared makefile for Linux and MacOSX
2014-09-30 09:58:03 +02:00
9bb95db68a opengl_example makefile cross platform supported. 2014-09-30 10:21:39 +09:00
0a8acf241c Update README.md 2014-09-29 19:27:21 +01:00
c388c7e6eb Update README.md 2014-09-29 19:26:45 +01:00
088df3d1ba Update README.md 2014-09-29 19:25:36 +01:00
09fae1c209 Update README.md 2014-09-26 01:28:03 +01:00
016dbb7472 Added screenshot for website 2014-09-26 01:25:06 +01:00
6ec65c46aa Added M+ font extra_fonts/ for Japanese text 2014-09-26 01:21:43 +01:00
0fa3d6e25f Version number and font documentation 2014-09-26 01:20:56 +01:00
f898e658bb Added IO.FontFallbackGlyph (default to '?') + UTF-8 test in demo window 2014-09-26 01:06:27 +01:00
22fe7f23b1 OpenGL example: minor tweak for non-default font. 2014-09-26 01:04:31 +01:00
b756510f21 Fix stb_image to load 1/2/4 bpp PNG (unofficial fix, submitted as PR) 2014-09-26 01:02:03 +01:00
b6ac371496 Warning fix 2014-09-25 20:55:48 +01:00
81b9480413 Speculative warning fixes 2014-09-25 20:08:08 +01:00
b9d9f62ae3 OpenGL example: updated stb_image to 1.46 2014-09-25 19:01:50 +01:00
4b94454fb4 OpenGL/DirectX examples: support for international text input in UTF-8 + implement ImeSetInputScreenPosFn on Windows. 2014-09-25 14:54:19 +01:00
b86505bf2f Support for international text input in UTF-8. Added ImeSetInputScreenPosFn(). Removed text_end parameter from SetClipboardTextF 2014-09-25 14:51:06 +01:00
df1c056c88 OpenGL example: added commented code to load custom font from filesystem 2014-09-25 11:41:18 +01:00
eb1b9d4521 Revert erroneous commit 2014-09-25 11:38:45 +01:00
d35ceb793e OpenGL example: added commented code to load custom font from filesystem 2014-09-25 11:35:23 +01:00
a61b92f362 Merge branch 'master' of https://github.com/ocornut/imgui 2014-09-25 11:30:07 +01:00
51bbe1d961 Handle UTF-8 decoding for rendering and text size calculation 2014-09-25 11:29:59 +01:00
e4d4dae3bf Merge pull request #49 from ybunyak/master
Fix build errors
2014-09-25 00:51:55 +02:00
bd3c53754d Fix build errors. 2014-09-25 01:45:54 +03:00
a1162ac001 Tab to spaces 2014-09-24 20:39:39 +01:00
618a42acf8 Renamed section in documentation 2014-09-24 19:35:34 +01:00
3cd1b8a37b Update version number in sources 2014-09-24 19:34:03 +01:00
746951691a Added va_list variations of all functions taking ... parameters (from Andrea Pessino) 2014-09-24 19:27:29 +01:00
8eafb373f7 Warning fixes (from Andrea Pessino) 2014-09-24 18:57:52 +01:00
fec4232c79 Moved IM_MALLOC/IM_FREE/etc. to IO structure members one can set at runtime. 2014-09-24 18:01:07 +01:00
85672fec2e Added IsPosHoveringAnyWindow() 2014-09-24 15:49:15 +01:00
d5ed586d70 Added IsMouseHoveringWindow(), IsMouseHoveringAnyWindow() 2014-09-24 15:38:29 +01:00
d58a029285 Tweak comments following feedbacks. 2014-09-24 14:12:51 +01:00
6e039c8b7d Doc formatting + adding 'API changes' section 2014-09-24 14:06:34 +01:00
05a42ba3a6 Added IO.FontBaseScale for global rescale. Renamed SetFontScale to SetWindowFontScale 2014-09-24 14:03:42 +01:00
da2ccf0a78 OpenGL example: comments on glfw window size vs frame buffer size. 2014-09-24 13:47:55 +01:00
3e647d86aa Merge pull request #47 from ybunyak/master
MacOS X examples fixes
2014-09-24 14:40:47 +02:00
0e0cd5e705 Add support for Retina displays on MacOSX. 2014-09-20 01:48:10 +03:00
8d32fcb7d4 Add missing framework for MacOSX builds. 2014-09-20 00:28:44 +03:00
4ea2af7ea5 Fixed wrong array size in header file (apessino) 2014-09-17 22:43:05 +01:00
3773fb4117 Update README.md 2014-09-10 12:40:52 +01:00
24028911e3 Added version number in sources 2014-09-10 12:26:12 +01:00
3fd68c3a31 Fixed file-descriptor leak if ImBitmapFont::LoadFromFile() calls to seek/tell fails. 2014-09-10 12:21:38 +01:00
1cf4b313e2 Update README.md 2014-09-10 11:35:34 +01:00
2e85dce1ee Added #define IMGUI_INCLUDE_IMGUI_USER_CPP to optionally include imgui_user.cpp 2014-09-10 11:22:01 +01:00
62d233aaab Added extra_flags parameters to InputInt(), InputFloat(). Used in example code. Commented out broken ImGuiInputTextFlags_AlignCenter. 2014-09-08 16:50:09 +01:00
3cdb4fa456 Merge pull request #44 from xythobuz/master
Added ImGuiInputTextFlags_EnterReturnsTrue
2014-09-08 16:37:16 +01:00
7439df0ba1 Added ImGuiInputTextFlags_EnterReturnsTrue 2014-09-08 15:48:39 +02:00
ad42787543 Made radio button render ascii when logged into tty/file/clipboard 2014-09-02 14:36:03 +01:00
91059da1a5 Added more comments in the code. 2014-09-02 14:35:06 +01:00
b420a51541 Update README.md
Fixed typos, reworded sentence.
2014-09-02 10:59:14 +01:00
29 changed files with 3729 additions and 1348 deletions

6
.gitignore vendored
View File

@ -1,7 +1,13 @@
## 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/*

View File

@ -1,9 +1,9 @@
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 simple 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 (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 designed to enable fast iteration and allow programmers to create "content creation" or "debug" tools (as opposed to tools for the average end-user). It favors simplicity and thus lacks certain features normally found in more high-level libraries, such as string localisation.
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.
@ -13,6 +13,8 @@ After ImGui is setup in your engine, you can use it like in this example:
ImGui outputs vertex buffers and simple command-lists that you can render in your application. Because it doesn't know or touch graphics state directly, you can call ImGui commands anywhere in your code (e.g. in the middle of a running algorithm, or in the middle of your own rendering process). Refer to the sample applications in the examples/ folder for instructions on how to integrate ImGui with your existing codebase.
ImGui allows you create elaborate tools as well as very short-lived ones. On the extreme side of short-liveness: using the Edit&Continue feature of compilers you can add a few widgets to tweaks variables while your application is running, and remove the code a minute later! ImGui is not just for tweaking values. You can use it to trace a running algorithm by just emitting text commands. You can use it along with your own reflection data to browse your dataset live. You can use it to expose the internals of a subsystem in your engine, to create a logger, an inspection tool, a profiler, a debugger, etc.
Gallery
-------
@ -21,6 +23,10 @@ Gallery
![screenshot 3](/web/test_window_03.png?raw=true)
![screenshot 4](/web/test_window_04.png?raw=true)
UTF-8 is supported for text display and input. Here using M+ font to display Japanese:
![utf-8 screenshot](/web/utf8_sample_01.png?raw=true)
References
----------
@ -32,9 +38,10 @@ 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) and the uSynergy.c micro client to share your mouse and keyboard. This way you can seemingly use your PC input devices on 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>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 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>I integrated ImGui in my engine and the text or lines are blurry..</b>
@ -45,19 +52,48 @@ I recommend using [Synergy](http://synergy-project.org) and the uSynergy.c micro
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>Why using C++ (as opposed to C)?</b>
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.
Support
-------
<b>Can you develop features xxxx for ImGui?</b>
Please use GitHub 'Issues' facilities to suggest and discuss improvements. Your questions are often helpul to the community of users. If you represent an organization and would like specific non-trivial features to be implemented, I am available for hire to work on or with ImGui.
<b>Can I donate to support the development of ImGui?</b>
If you have the mean to help, I have setup a [**Patreon page**](http://www.patreon.com/imgui) to enable me to spend more time on the development of the library. One-off donations are also greatly appreciated. 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).
Embeds [proggy_clean](http://upperbounds.net) font by Tristan Grimmer (also MIT license).
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.
Inspiration, feedback, and testing: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. Thanks!

View File

@ -0,0 +1,84 @@
<?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>
<ItemGroup>
<None Include="..\..\LICENSE" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,38 @@
<?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>
<ItemGroup>
<None Include="..\..\LICENSE">
<Filter>imgui</Filter>
</None>
</ItemGroup>
</Project>

View File

@ -0,0 +1,607 @@
#include <windows.h>
#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
extern const char* vertexShader; // Implemented at the bottom
extern const char* pixelShader;
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
{
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
{
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::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::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;
}
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;\
}";
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;\
}";

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;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;user32.lib</AdditionalDependencies>
<AdditionalDependencies>d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;imm32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>
</SubSystem>
</Link>

View File

@ -1,22 +1,23 @@
#include <windows.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)
@ -42,12 +43,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++;
}
@ -91,9 +92,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);
@ -102,7 +103,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;
@ -123,19 +124,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)
@ -153,8 +153,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.)
@ -163,15 +162,13 @@ LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
return true;
case WM_CHAR:
// You can also use ToAscii()+GetKeyboardState() to retrieve characters.
if (wParam > 1 && wParam < 256)
io.AddInputCharacter((char)wParam);
if (wParam > 0 && wParam < 0x10000)
io.AddInputCharacter((unsigned short)wParam);
return true;
case WM_DESTROY:
{
Cleanup();
PostQuitMessage(0);
return 0;
}
CleanupDevice();
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
@ -180,12 +177,14 @@ 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;
@ -224,17 +223,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)
@ -255,7 +254,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
@ -263,14 +262,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;
}
@ -295,36 +293,31 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
UpdateImGui();
// Create a simple window
// Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug"
static bool show_test_window = true;
static bool show_another_window = false;
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 framerate
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);
// Show the ImGui test window
// Most of user example code is in ImGui::ShowTestWindow()
if (show_test_window)
// 1. Show a simple window
// Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug"
{
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::ShowTestWindow(&show_test_window);
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);
}
// Show another simple window
// 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));
@ -332,6 +325,13 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
ImGui::End();
}
// 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::ShowTestWindow(&show_test_window);
}
// Rendering
g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, false);
g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
@ -347,9 +347,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,32 @@

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
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
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,53 @@
#
# 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`
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/usr/local/Cellar/glew/1.10.0/include -I/usr/local/include
CXXFLAGS += -I../../
# 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

@ -1,18 +0,0 @@
#
# Quick and dirty makefile to build on Linux
# tested on Ubuntu 14.04.1 32bit
#
SRC = main.cpp ../../imgui.cpp
OBJ = $(SRC:.cpp=.o)
CXXFLAGS = -I../../ `pkg-config --cflags glfw3`
LIBS = `pkg-config --static --libs glfw3` -lGLEW
all: $(OBJ)
$(CXX) $(OBJ) $(LIBS)
clean:
$(RM) -f $(OBJ)

View File

@ -1,18 +0,0 @@
# This makefile currently only works for mac os
# You should install via homebrew:
# brew install glew
# brew install glfw3
#
CXXFLAGS=-framework OpenGL -framework Cocoa -framework IOKit
CXXFLAGS+=-I/usr/local/Cellar/glew/1.10.0/include -I/usr/local/Cellar/glfw3/3.0.4/include
CXXFLAGS+=-L/usr/local/Cellar/glew/1.10.0/lib -L/usr/local/Cellar/glfw3/3.0.4/lib
CXXFLAGS+=-lglew -lglfw3
CXXFLAGS+=-I../../
CXXFLAGS+= -D__APPLE__
main: main.cpp ../../imgui.cpp
$(CXX) $(CXXFLAGS) -o $@ $^
clean:
rm main

View File

@ -1,15 +1,25 @@
#ifdef _MSC_VER
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
#include <Windows.h>
#endif
#define STB_IMAGE_IMPLEMENTATION
#include "../shared/stb_image.h" // for .png loading
#include "../../imgui.h"
// glew & glfw
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h" // for .png loading
#include "../../imgui.h"
#ifdef _MSC_VER
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
#define GLFW_EXPOSE_NATIVE_WIN32
#define GLFW_EXPOSE_NATIVE_WGL
#include <GLFW/glfw3native.h>
#endif
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:
@ -23,6 +33,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);
@ -40,72 +51,70 @@ 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.
static const char* ImImpl_GetClipboardTextFn()
{
return glfwGetClipboardString(window);
}
static void ImImpl_SetClipboardTextFn(const char* text, const char* text_end)
static void ImImpl_SetClipboardTextFn(const char* text)
{
if (!text_end)
text_end = text + strlen(text);
if (*text_end == 0)
{
// Already got a zero-terminator at 'text_end', we don't need to add one
glfwSetClipboardString(window, text);
}
else
{
// Add a zero-terminator because glfw function doesn't take a size
char* buf = (char*)malloc(text_end - text + 1);
memcpy(buf, text, text_end-text);
buf[text_end-text] = '\0';
glfwSetClipboardString(window, buf);
free(buf);
}
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 = (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)
@ -121,8 +130,8 @@ static void glfw_key_callback(GLFWwindow* window, int key, int scancode, int act
static void glfw_char_callback(GLFWwindow* window, unsigned int c)
{
if (c > 0 && c <= 255)
ImGui::GetIO().AddInputCharacter((char)c);
if (c > 0 && c < 0x10000)
ImGui::GetIO().AddInputCharacter((unsigned short)c);
}
// OpenGL code based on http://open.gl tutorials
@ -137,6 +146,7 @@ void InitGL()
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);
@ -146,13 +156,17 @@ void InitGL()
void InitImGui()
{
int w, h;
int display_w, display_h;
glfwGetWindowSize(window, &w, &h);
glfwGetFramebufferSize(window, &display_w, &display_h);
mousePosScale.x = (float)display_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)display_h / h;
ImGuiIO& io = ImGui::GetIO();
io.DisplaySize = ImVec2((float)w, (float)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.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 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;
@ -179,11 +193,35 @@ void InitImGui()
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);
#if 1
// 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);
#else
// Custom font from filesystem
io.Font = new ImFont();
io.Font->LoadFromFile("../../extra_fonts/mplus-2m-medium_18.fnt");
IM_ASSERT(io.Font->IsLoaded());
int tex_x, tex_y, tex_comp;
void* tex_data = stbi_load("../../extra_fonts/mplus-2m-medium_18.png", &tex_x, &tex_y, &tex_comp, 0);
IM_ASSERT(tex_data != NULL);
// Automatically find white pixel from the texture we just loaded
// (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.Font->TexUvForWhite = ImVec2((float)(tex_data_off % tex_x)/(tex_x), (float)(tex_data_off / tex_x)/(tex_y));
break;
}
#endif
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_x, tex_y, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_data);
stbi_image_free(tex_data);
}
@ -192,7 +230,7 @@ void UpdateImGui()
{
ImGuiIO& io = ImGui::GetIO();
// Setup timestep
// Setup time step
static double time = 0.0f;
const double current_time = glfwGetTime();
io.DeltaTime = (float)(current_time - time);
@ -202,9 +240,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, (float)mouse_y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
io.MouseDown[0] = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) != 0;
io.MouseDown[1] = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) != 0;
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.)
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();
@ -219,40 +257,35 @@ int main(int argc, char** argv)
while (!glfwWindowShouldClose(window))
{
ImGuiIO& io = ImGui::GetIO();
io.MouseWheel = 0;
mousePressed[0] = mousePressed[1] = false;
glfwPollEvents();
UpdateImGui();
// Create a simple window
// Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug"
static bool show_test_window = true;
static bool show_another_window = false;
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 framerate
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);
// Show the ImGui test window
// Most of user example code is in ImGui::ShowTestWindow()
if (show_test_window)
// 1. Show a simple window
// Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug"
{
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::ShowTestWindow(&show_test_window);
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);
}
// Show another simple window
// 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));
@ -260,6 +293,13 @@ int main(int argc, char** argv)
ImGui::End();
}
// 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::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);

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

@ -46,7 +46,7 @@
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\glfw\lib-msvc100;$(SolutionDir)\glew\lib\Release\Win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>opengl32.lib;glfw3.lib;glew32s.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>opengl32.lib;imm32.lib;glfw3.lib;glew32s.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>NotSet</SubSystem>
</Link>
</ItemDefinitionGroup>
@ -63,7 +63,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(SolutionDir)\glfw\lib-msvc100;$(SolutionDir)\glew\lib\Release\Win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>opengl32.lib;glfw3.lib;glew32s.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>opengl32.lib;imm32.lib;glfw3.lib;glew32s.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>NotSet</SubSystem>
</Link>
</ItemDefinitionGroup>
@ -75,7 +75,7 @@
<ClInclude Include="..\..\imconfig.h" />
<ClInclude Include="..\..\imgui.h" />
<ClInclude Include="..\..\stb_textedit.h" />
<ClInclude Include="stb_image.h" />
<ClInclude Include="..\shared\stb_image.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\LICENSE" />

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,6 +27,9 @@
<ClInclude Include="..\..\stb_textedit.h">
<Filter>imgui</Filter>
</ClInclude>
<ClInclude Include="..\shared\stb_image.h">
<Filter>sources</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\LICENSE">

View File

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

View File

@ -1,4 +1,4 @@
/* stb_image - v1.43 - public domain JPEG/PNG reader - http://nothings.org/stb_image.c
/* stb_image - v1.46 - public domain JPEG/PNG reader - http://nothings.org/stb_image.c
when you control the images you're loading
no warranty implied; use at your own risk
@ -13,7 +13,7 @@
avoid problematic images and only need the trivial interface
JPEG baseline (no JPEG progressive)
PNG 8-bit-per-channel only
PNG 1/2/4/8-bit-per-channel (16 bpc not supported)
TGA (not sure what subset, if a subset)
BMP non-1bpp, non-RLE
@ -28,11 +28,15 @@
- overridable dequantizing-IDCT, YCbCr-to-RGB conversion (define STBI_SIMD)
Latest revisions:
1.xx (2014-09-26) 1/2/4-bit PNG support (both grayscale and paletted)
1.46 (2014-08-26) fix broken tRNS chunk in non-paletted PNG
1.45 (2014-08-16) workaround MSVC-ARM internal compiler error by wrapping malloc
1.44 (2014-08-07) warnings
1.43 (2014-07-15) fix MSVC-only bug in 1.42
1.42 (2014-07-09) no _CRT_SECURE_NO_WARNINGS; error-path fixes; STBI_ASSERT
1.41 (2014-06-25) fix search&replace that messed up comments/error messages
1.40 (2014-06-22) gcc warning
1.39 (2014-06-15) TGA optimization fix, multiple BMP fixes
1.39 (2014-06-15) TGA optimization bugfix, multiple BMP fixes
1.38 (2014-06-06) suppress MSVC run-time warnings, fix accidental rename of 'skip'
1.37 (2014-06-04) remove duplicate typedef
1.36 (2014-06-03) converted to header file, allow reading incorrect iphoned-images without iphone flag
@ -60,17 +64,19 @@
James "moose2000" Brown (iPhone PNG) David Woo
Ben "Disch" Wenger (io callbacks) Roy Eltham
Martin "SpartanJ" Golini Luke Graham
Thomas Ruf
Omar Cornut (1/2/4-bit png) Thomas Ruf
John Bartholomew
Optimizations & bugfixes Ken Hamada
Fabian "ryg" Giesen Cort Stratton
Arseny Kapoulkine Blazej Dariusz Roszkowski
Thibault Reuille
If your name should be here but Paul Du Bois
isn't, let Sean know. Guillaume George
Paul Du Bois
Guillaume George
Jerry Jansson
Hayaki Saito
Johan Duparc
If your name should be here but Hayaki Saito
isn't, let Sean know. Johan Duparc
Ronny Chevalier
Michal Cichon
*/
#ifndef STBI_INCLUDE_STB_IMAGE_H
@ -525,6 +531,11 @@ static int stbi__err(const char *str)
return 0;
}
static void *stbi__malloc(size_t size)
{
return malloc(size);
}
// stbi__err - error
// stbi__errpf - error returning pointer to float
// stbi__errpuc - error returning pointer to unsigned char
@ -577,11 +588,11 @@ static unsigned char *stbi_load_main(stbi__context *s, int *x, int *y, int *comp
FILE *stbi__fopen(char const *filename, char const *mode)
{
FILE *f;
#if _MSC_VER >= 1400
if (0 != fopen_s(&f, filename, "rb"))
#if defined(_MSC_VER) && _MSC_VER >= 1400
if (0 != fopen_s(&f, filename, mode))
f=0;
#else
f = fopen(filename, "rb");
f = fopen(filename, mode);
#endif
return f;
}
@ -756,7 +767,7 @@ static void stbi__refill_buffer(stbi__context *s)
int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen);
if (n == 0) {
// at end of file, treat same as if from memory, but need to handle case
// where s->img_buffer isn't pointing to safe memory, stbi__err.g. 0-byte file
// where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file
s->read_from_callbacks = 0;
s->img_buffer = s->buffer_start;
s->img_buffer_end = s->buffer_start+1;
@ -854,7 +865,7 @@ static stbi__uint32 stbi__get32le(stbi__context *s)
//////////////////////////////////////////////////////////////////////////////
//
// generic converter from built-in img_n to req_comp
// individual types do this automatically as much as possible (stbi__err.g. jpeg
// individual types do this automatically as much as possible (e.g. jpeg
// does all cases internally since it needs to colorspace convert anyway,
// and it never has alpha, so very few cases ). png can automatically
// interleave an alpha=255 channel, but falls back to this for other cases
@ -875,7 +886,7 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r
if (req_comp == img_n) return data;
STBI_ASSERT(req_comp >= 1 && req_comp <= 4);
good = (unsigned char *) malloc(req_comp * x * y);
good = (unsigned char *) stbi__malloc(req_comp * x * y);
if (good == NULL) {
free(data);
return stbi__errpuc("outofmem", "Out of memory");
@ -915,7 +926,7 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r
static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp)
{
int i,k,n;
float *output = (float *) malloc(x * y * comp * sizeof(float));
float *output = (float *) stbi__malloc(x * y * comp * sizeof(float));
if (output == NULL) { free(data); return stbi__errpf("outofmem", "Out of memory"); }
// compute number of non-alpha components
if (comp & 1) n = comp; else n = comp-1;
@ -933,7 +944,7 @@ static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp)
static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp)
{
int i,k,n;
stbi_uc *output = (stbi_uc *) malloc(x * y * comp);
stbi_uc *output = (stbi_uc *) stbi__malloc(x * y * comp);
if (output == NULL) { free(data); return stbi__errpuc("outofmem", "Out of memory"); }
// compute number of non-alpha components
if (comp & 1) n = comp; else n = comp-1;
@ -1601,16 +1612,16 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h;
for (i=0; i < s->img_n; ++i) {
// number of effective pixels (stbi__err.g. for non-interleaved MCU)
// number of effective pixels (e.g. for non-interleaved MCU)
z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max-1) / h_max;
z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max-1) / v_max;
// to simplify generation, we'll allocate enough memory to decode
// the bogus oversized data from using interleaved MCUs and their
// big blocks (stbi__err.g. a 16x16 iMCU on an image of width 33); we won't
// big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't
// discard the extra data until colorspace conversion
z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8;
z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8;
z->img_comp[i].raw_data = malloc(z->img_comp[i].w2 * z->img_comp[i].h2+15);
z->img_comp[i].raw_data = stbi__malloc(z->img_comp[i].w2 * z->img_comp[i].h2+15);
if (z->img_comp[i].raw_data == NULL) {
for(--i; i >= 0; --i) {
free(z->img_comp[i].raw_data);
@ -1626,7 +1637,7 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
return 1;
}
// use comparisons since in some cases we handle more than one case (stbi__err.g. stbi__SOF)
// use comparisons since in some cases we handle more than one case (e.g. stbi__SOF)
#define stbi__DNL(x) ((x) == 0xdc)
#define stbi__SOI(x) ((x) == 0xd8)
#define stbi__EOI(x) ((x) == 0xd9)
@ -1875,7 +1886,7 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
// allocate line buffer big enough for upsampling off the edges
// with upsample factor of 4
z->img_comp[k].linebuf = (stbi_uc *) malloc(z->s->img_x + 3);
z->img_comp[k].linebuf = (stbi_uc *) stbi__malloc(z->s->img_x + 3);
if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); }
r->hs = z->img_h_max / z->img_comp[k].h;
@ -1893,7 +1904,7 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
}
// can't error after this so, this is safe
output = (stbi_uc *) malloc(n * z->s->img_x * z->s->img_y + 1);
output = (stbi_uc *) stbi__malloc(n * z->s->img_x * z->s->img_y + 1);
if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); }
// now go ahead and resample
@ -2015,7 +2026,7 @@ stbi_inline static int stbi__bit_reverse(int v, int bits)
{
STBI_ASSERT(bits <= 16);
// to bit reverse n bits, reverse 16 and shift
// stbi__err.g. 11 bits, bit reverse and shift away 5
// e.g. 11 bits, bit reverse and shift away 5
return stbi__bitreverse16(v) >> (16-bits);
}
@ -2338,7 +2349,7 @@ static int stbi__do_zlib(stbi__zbuf *a, char *obuf, int olen, int exp, int parse
STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen)
{
stbi__zbuf a;
char *p = (char *) malloc(initial_size);
char *p = (char *) stbi__malloc(initial_size);
if (p == NULL) return NULL;
a.zbuffer = (stbi_uc *) buffer;
a.zbuffer_end = (stbi_uc *) buffer + len;
@ -2359,7 +2370,7 @@ STBIDEF char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen)
STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header)
{
stbi__zbuf a;
char *p = (char *) malloc(initial_size);
char *p = (char *) stbi__malloc(initial_size);
if (p == NULL) return NULL;
a.zbuffer = (stbi_uc *) buffer;
a.zbuffer_end = (stbi_uc *) buffer + len;
@ -2386,7 +2397,7 @@ STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer
STBIDEF char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen)
{
stbi__zbuf a;
char *p = (char *) malloc(16384);
char *p = (char *) stbi__malloc(16384);
if (p == NULL) return NULL;
a.zbuffer = (stbi_uc *) buffer;
a.zbuffer_end = (stbi_uc *) buffer+len;
@ -2477,89 +2488,144 @@ static int stbi__paeth(int a, int b, int c)
#define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings
// create the png data from post-deflated data
static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y)
static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color)
{
stbi__context *s = a->s;
stbi__uint32 i,j,stride = x*out_n;
stbi__uint32 img_len;
int k;
int img_n = s->img_n; // copy it into a local for later
stbi_uc* line8 = NULL; // point into raw when depth==8 else temporary local buffer
STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1);
a->out = (stbi_uc *) malloc(x * y * out_n);
a->out = (stbi_uc *) stbi__malloc(x * y * out_n);
if (!a->out) return stbi__err("outofmem", "Out of memory");
img_len = ((((img_n * x * depth) + 7) >> 3) + 1) * y;
if (s->img_x == x && s->img_y == y) {
if (raw_len != (img_n * x + 1) * y) return stbi__err("not enough pixels","Corrupt PNG");
if (raw_len != img_len) return stbi__err("not enough pixels","Corrupt PNG");
} else { // interlaced:
if (raw_len < (img_n * x + 1) * y) return stbi__err("not enough pixels","Corrupt PNG");
if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG");
}
if (depth != 8) {
line8 = (stbi_uc *) stbi__malloc((x+7) * out_n); // allocate buffer for one scanline
if (!line8) return stbi__err("outofmem", "Out of memory");
}
for (j=0; j < y; ++j) {
stbi_uc *in;
stbi_uc *cur = a->out + stride*j;
stbi_uc *prior = cur - stride;
int filter = *raw++;
if (filter > 4) return stbi__err("invalid filter","Corrupt PNG");
if (filter > 4) {
if (depth != 8) free(line8);
return stbi__err("invalid filter","Corrupt PNG");
}
if (depth == 8) {
in = raw;
raw += x*img_n;
}
else {
// unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit
// png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop
in = line8;
stbi_uc* decode_out = line8;
stbi_uc scale = (color == 0) ? 0xFF/((1<<depth)-1) : 1; // scale grayscale values to 0..255 range
if (depth == 4) {
for (k=x*img_n; k >= 1; k-=2, raw++) {
*decode_out++ = scale * ((*raw >> 4) );
*decode_out++ = scale * ((*raw ) & 0x0f);
}
} else if (depth == 2) {
for (k=x*img_n; k >= 1; k-=4, raw++) {
*decode_out++ = scale * ((*raw >> 6) );
*decode_out++ = scale * ((*raw >> 4) & 0x03);
*decode_out++ = scale * ((*raw >> 2) & 0x03);
*decode_out++ = scale * ((*raw ) & 0x03);
}
} else if (depth == 1) {
for (k=x*img_n; k >= 1; k-=8, raw++) {
*decode_out++ = scale * ((*raw >> 7) );
*decode_out++ = scale * ((*raw >> 6) & 0x01);
*decode_out++ = scale * ((*raw >> 5) & 0x01);
*decode_out++ = scale * ((*raw >> 4) & 0x01);
*decode_out++ = scale * ((*raw >> 3) & 0x01);
*decode_out++ = scale * ((*raw >> 2) & 0x01);
*decode_out++ = scale * ((*raw >> 1) & 0x01);
*decode_out++ = scale * ((*raw ) & 0x01);
}
}
}
// if first row, use special filter that doesn't sample previous row
if (j == 0) filter = first_row_filter[filter];
// handle first pixel explicitly
for (k=0; k < img_n; ++k) {
switch (filter) {
case STBI__F_none : cur[k] = raw[k]; break;
case STBI__F_sub : cur[k] = raw[k]; break;
case STBI__F_up : cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break;
case STBI__F_avg : cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1)); break;
case STBI__F_paeth : cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0,prior[k],0)); break;
case STBI__F_avg_first : cur[k] = raw[k]; break;
case STBI__F_paeth_first: cur[k] = raw[k]; break;
case STBI__F_none : cur[k] = in[k]; break;
case STBI__F_sub : cur[k] = in[k]; break;
case STBI__F_up : cur[k] = STBI__BYTECAST(in[k] + prior[k]); break;
case STBI__F_avg : cur[k] = STBI__BYTECAST(in[k] + (prior[k]>>1)); break;
case STBI__F_paeth : cur[k] = STBI__BYTECAST(in[k] + stbi__paeth(0,prior[k],0)); break;
case STBI__F_avg_first : cur[k] = in[k]; break;
case STBI__F_paeth_first: cur[k] = in[k]; break;
}
}
if (img_n != out_n) cur[img_n] = 255;
raw += img_n;
in += img_n;
cur += out_n;
prior += out_n;
// this is a little gross, so that we don't switch per-pixel or per-component
if (img_n == out_n) {
#define CASE(f) \
case f: \
for (i=x-1; i >= 1; --i, raw+=img_n,cur+=img_n,prior+=img_n) \
for (i=x-1; i >= 1; --i, in+=img_n,cur+=img_n,prior+=img_n) \
for (k=0; k < img_n; ++k)
switch (filter) {
CASE(STBI__F_none) cur[k] = raw[k]; break;
CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(raw[k] + cur[k-img_n]); break;
CASE(STBI__F_up) cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break;
CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-img_n])>>1)); break;
CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-img_n],prior[k],prior[k-img_n])); break;
CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(raw[k] + (cur[k-img_n] >> 1)); break;
CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-img_n],0,0)); break;
CASE(STBI__F_none) cur[k] = in[k]; break;
CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(in[k] + cur[k-img_n]); break;
CASE(STBI__F_up) cur[k] = STBI__BYTECAST(in[k] + prior[k]); break;
CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(in[k] + ((prior[k] + cur[k-img_n])>>1)); break;
CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(in[k] + stbi__paeth(cur[k-img_n],prior[k],prior[k-img_n])); break;
CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(in[k] + (cur[k-img_n] >> 1)); break;
CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(in[k] + stbi__paeth(cur[k-img_n],0,0)); break;
}
#undef CASE
} else {
STBI_ASSERT(img_n+1 == out_n);
#define CASE(f) \
case f: \
for (i=x-1; i >= 1; --i, cur[img_n]=255,raw+=img_n,cur+=out_n,prior+=out_n) \
for (i=x-1; i >= 1; --i, cur[img_n]=255,in+=img_n,cur+=out_n,prior+=out_n) \
for (k=0; k < img_n; ++k)
switch (filter) {
CASE(STBI__F_none) cur[k] = raw[k]; break;
CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(raw[k] + cur[k-out_n]); break;
CASE(STBI__F_up) cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break;
CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-out_n])>>1)); break;
CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-out_n],prior[k],prior[k-out_n])); break;
CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(raw[k] + (cur[k-out_n] >> 1)); break;
CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-out_n],0,0)); break;
CASE(STBI__F_none) cur[k] = in[k]; break;
CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(in[k] + cur[k-out_n]); break;
CASE(STBI__F_up) cur[k] = STBI__BYTECAST(in[k] + prior[k]); break;
CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(in[k] + ((prior[k] + cur[k-out_n])>>1)); break;
CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(in[k] + stbi__paeth(cur[k-out_n],prior[k],prior[k-out_n])); break;
CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(in[k] + (cur[k-out_n] >> 1)); break;
CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(in[k] + stbi__paeth(cur[k-out_n],0,0)); break;
}
#undef CASE
}
}
if (depth != 8) free(line8);
return 1;
}
static int stbi__create_png_image(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, int interlaced)
static int stbi__create_png_image(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, int depth, int color, int interlaced)
{
stbi_uc *final;
int p;
if (!interlaced)
return stbi__create_png_image_raw(a, raw, raw_len, out_n, a->s->img_x, a->s->img_y);
return stbi__create_png_image_raw(a, raw, raw_len, out_n, a->s->img_x, a->s->img_y, depth, color);
// de-interlacing
final = (stbi_uc *) malloc(a->s->img_x * a->s->img_y * out_n);
final = (stbi_uc *) stbi__malloc(a->s->img_x * a->s->img_y * out_n);
for (p=0; p < 7; ++p) {
int xorig[] = { 0,4,0,2,0,1,0 };
int yorig[] = { 0,0,4,0,2,0,1 };
@ -2570,7 +2636,8 @@ static int stbi__create_png_image(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_l
x = (a->s->img_x - xorig[p] + xspc[p]-1) / xspc[p];
y = (a->s->img_y - yorig[p] + yspc[p]-1) / yspc[p];
if (x && y) {
if (!stbi__create_png_image_raw(a, raw, raw_len, out_n, x, y)) {
stbi__uint32 img_len = ((((out_n * x * depth) + 7) >> 3) + 1) * y;
if (!stbi__create_png_image_raw(a, raw, raw_len, out_n, x, y, depth, color)) {
free(final);
return 0;
}
@ -2579,8 +2646,8 @@ static int stbi__create_png_image(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_l
memcpy(final + (j*yspc[p]+yorig[p])*a->s->img_x*out_n + (i*xspc[p]+xorig[p])*out_n,
a->out + (j*x+i)*out_n, out_n);
free(a->out);
raw += (x*out_n+1)*y;
raw_len -= (x*out_n+1)*y;
raw += img_len;
raw_len -= img_len;
}
}
a->out = final;
@ -2618,7 +2685,7 @@ static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int
stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y;
stbi_uc *p, *temp_out, *orig = a->out;
p = (stbi_uc *) malloc(pixel_count * pal_img_n);
p = (stbi_uc *) stbi__malloc(pixel_count * pal_img_n);
if (p == NULL) return stbi__err("outofmem", "Out of memory");
// between here and free(out) below, exitting would leak
@ -2710,7 +2777,7 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
stbi_uc palette[1024], pal_img_n=0;
stbi_uc has_trans=0, tc[3];
stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0;
int first=1,k,interlace=0, is_iphone=0;
int first=1,k,interlace=0, color=0, depth=0, is_iphone=0;
stbi__context *s = z->s;
z->expanded = NULL;
@ -2729,13 +2796,13 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
stbi__skip(s, c.length);
break;
case PNG_TYPE('I','H','D','R'): {
int depth,color,comp,filter;
int comp,filter;
if (!first) return stbi__err("multiple IHDR","Corrupt PNG");
first = 0;
if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG");
s->img_x = stbi__get32be(s); if (s->img_x > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
depth = stbi__get8(s); if (depth != 8) return stbi__err("8bit only","PNG not supported: 8-bit only");
depth = stbi__get8(s); if (depth != 1 && depth != 2 && depth != 4 && depth != 8) return stbi__err("1/2/4/8-bit only","PNG not supported: 1/2/4/8-bit only");
color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG");
if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG");
comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG");
@ -2819,7 +2886,7 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
s->img_out_n = s->img_n+1;
else
s->img_out_n = s->img_n;
if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, interlace)) return 0;
if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, depth, color, interlace)) return 0;
if (has_trans)
if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0;
if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2)
@ -2872,7 +2939,7 @@ static unsigned char *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req
}
*x = p->s->img_x;
*y = p->s->img_y;
if (n) *n = p->s->img_n;
if (n) *n = p->s->img_out_n;
}
free(p->out); p->out = NULL;
free(p->expanded); p->expanded = NULL;
@ -3074,7 +3141,7 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
target = req_comp;
else
target = s->img_n; // if they want monochrome, we'll post-convert
out = (stbi_uc *) malloc(target * s->img_x * s->img_y);
out = (stbi_uc *) stbi__malloc(target * s->img_x * s->img_y);
if (!out) return stbi__errpuc("outofmem", "Out of memory");
if (bpp < 16) {
int z=0;
@ -3303,7 +3370,7 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
*y = tga_height;
if (comp) *comp = tga_comp;
tga_data = (unsigned char*)malloc( tga_width * tga_height * tga_comp );
tga_data = (unsigned char*)stbi__malloc( tga_width * tga_height * tga_comp );
if (!tga_data) return stbi__errpuc("outofmem", "Out of memory");
// skip to the data's starting position (offset usually = 0)
@ -3322,7 +3389,7 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
// any data to skip? (offset usually = 0)
stbi__skip(s, tga_palette_start );
// load the palette
tga_palette = (unsigned char*)malloc( tga_palette_len * tga_palette_bits / 8 );
tga_palette = (unsigned char*)stbi__malloc( tga_palette_len * tga_palette_bits / 8 );
if (!tga_palette) {
free(tga_data);
return stbi__errpuc("outofmem", "Out of memory");
@ -3513,7 +3580,7 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
return stbi__errpuc("bad compression", "PSD has an unknown compression format");
// Create the destination image.
out = (stbi_uc *) malloc(4 * w*h);
out = (stbi_uc *) stbi__malloc(4 * w*h);
if (!out) return stbi__errpuc("outofmem", "Out of memory");
pixelCount = w*h;
@ -3798,7 +3865,7 @@ static stbi_uc *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int re
stbi__get16be(s); //skip `pad'
// intermediate buffer is RGBA
result = (stbi_uc *) malloc(x*y*4);
result = (stbi_uc *) stbi__malloc(x*y*4);
memset(result, 0xff, x*y*4);
if (!stbi__pic_load_core(s,x,y,comp, result)) {
@ -4049,14 +4116,14 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
if (g->out == 0) {
if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header
g->out = (stbi_uc *) malloc(4 * g->w * g->h);
g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h);
if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory");
stbi__fill_gif_background(g);
} else {
// animated-gif-only path
if (((g->eflags & 0x1C) >> 2) == 3) {
old_out = g->out;
g->out = (stbi_uc *) malloc(4 * g->w * g->h);
g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h);
if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory");
memcpy(g->out, old_out, g->w*g->h*4);
}
@ -4279,7 +4346,7 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
if (req_comp == 0) req_comp = 3;
// Read data
hdr_data = (float *) malloc(height * width * req_comp * sizeof(float));
hdr_data = (float *) stbi__malloc(height * width * req_comp * sizeof(float));
// Load image data
// image data is stored as some number of sca
@ -4318,7 +4385,7 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
len <<= 8;
len |= stbi__get8(s);
if (len != width) { free(hdr_data); free(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); }
if (scanline == NULL) scanline = (stbi_uc *) malloc(width * 4);
if (scanline == NULL) scanline = (stbi_uc *) stbi__malloc(width * 4);
for (k = 0; k < 4; ++k) {
i = 0;
@ -4555,6 +4622,12 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
/*
revision history:
1.46 (2014-08-26)
fix broken tRNS chunk (colorkey-style transparency) in non-paletted PNG
1.45 (2014-08-16)
fix MSVC-ARM internal compiler error by wrapping malloc
1.44 (2014-08-07)
various warning fixes from Ronny Chevalier
1.43 (2014-07-15)
fix MSVC-only compiler problem in code changed in 1.42
1.42 (2014-07-09)

View File

@ -10,12 +10,22 @@ bmfont reads fonts (.ttf, .fon, etc.) and output a .fnt file and a texture file,
proggy_clean.fon --> [bmfont] ---> proggy_clean_13.fnt
proggy_clean_13.png
If you need a free font that supports chinese/japanese characters, you can use the M+ fonts.
TTF and sources are availables at http://mplus-fonts.sourceforge.jp/mplus-outline-fonts.
This directory include some of the M+ fonts converted by bmfont.
//-----------------------------------------------------------------------------
Configure bmfont:
- Export .fnt as Binary
- Output .png, 32-bits (or whatever is suitable for your loader/renderer)
- Tip: uncheck "Render from TrueType outline" and "Font Smoothing" for best result with non-anti-aliased type fonts.
But you can experiment with other settings if you want anti-aliased fonts.
- Tip: use pngout.exe (http://advsys.net/ken/utils.htm) to further reduce the file size of .png files
All files in this folder have been optimised with pngout.exe
-----------------------------------------------------------------------------
(A) Use font data embedded in ImGui
@ -29,43 +39,62 @@ 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
//-----------------------------------------------------------------------------
(B) Use fonts from external files
ImGuiIO& io = ImGui::GetIO();
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.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.Font->TexUvForWhite = ImVec2((float)(tex_data_off % tex_x)/(tex_x), (float)(tex_data_off / tex_x)/(tex_y));
break;
}
1. Load the .FNT data, e.g.
ImGuiIO& io = ImGui::GetIO();
// proggy_clean_13 [default]
io.Font = new ImFont();
io.Font->LoadFromFile("proggy_clean_13.fnt");
io.FontTexUvForWhite = ImVec2(0.0f/256.0f,0.0f/128);
io.FontYOffset = +1;
IM_ASSERT(io.Font->IsLoaded());
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");
io.FontTexUvForWhite = ImVec2(84.0f/256.0f,20.0f/64);
io.FontYOffset = +2;
IM_ASSERT(io.Font->IsLoaded());
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");
io.FontTexUvForWhite = ImVec2(84.0f/256.0f,20.0f/64);
io.FontYOffset = +3;
IM_ASSERT(io.Font->IsLoaded());
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
//-----------------------------------------------------------------------------

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 KiB

View File

@ -1,14 +1,11 @@
//-----------------------------------------------------------------------------
// USER IMPLEMENTATION
// This file contains compile-time options for ImGui.
// Other options (memory allocation overrides, callbacks, etc.) can be set at runtime via the ImGuiIO structure - ImGui::GetIO().
//-----------------------------------------------------------------------------
#pragma once
//---- Define your own malloc/free/realloc functions if you want to override internal memory allocations for ImGui
//#define IM_MALLOC(_SIZE) MyMalloc(_SIZE) // void* MyMalloc(size_t size);
//#define IM_FREE(_PTR) MyFree(_PTR) // void MyFree(void *ptr);
//#define IM_REALLOC(_PTR, _SIZE) MyRealloc(_PTR, _SIZE) // void* MyRealloc(void *ptr, size_t size);
//---- Define your own ImVector<> type if you don't want to use the provided implementation defined in imgui.h
//#include <vector>
//#define ImVector std::vector
@ -17,9 +14,12 @@
//---- Define assertion handler. Defaults to calling assert().
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
//---- Don't implement default clipboard handlers for Windows (so as not to link with OpenClipboard(), etc.)
//---- Don't implement default clipboard handlers for Windows (so as not to link with OpenClipboard() and others Win32 functions)
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS
//---- 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
//---- Define implicit cast operators to convert back<>forth from your math types and ImVec2/ImVec4.
/*
#define IM_VEC2_CLASS_EXTRA \
@ -32,12 +32,13 @@
*/
//---- Freely implement extra functions within the ImGui:: namespace.
//---- Declare helpers or widgets implemented in imgui_user.inl or elsewhere, so end-user doesn't need to include multiple files.
//---- e.g. you can create variants of the ImGui::Value() helper for your low-level math types.
/*
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);
};
}
*/

2868
imgui.cpp

File diff suppressed because it is too large Load Diff

628
imgui.h
View File

@ -1,4 +1,4 @@
// ImGui library
// ImGui library v1.17 wip
// 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;
@ -17,33 +17,28 @@ struct ImGuiWindow;
#include "imconfig.h"
#include <float.h> // FLT_MAX
#include <stdarg.h> // va_list
#include <stddef.h> // ptrdiff_t
#include <stdlib.h> // NULL, malloc
#ifndef IM_MALLOC
#define IM_MALLOC(_SIZE) malloc((_SIZE))
#endif
#ifndef IM_FREE
#define IM_FREE(_PTR) free((_PTR))
#endif
#ifndef IM_REALLOC
#define IM_REALLOC(_PTR, _SIZE) realloc((_PTR), (_SIZE))
#endif
#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 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 ImGuiInputTextFlags; // enum ImGuiInputTextFlags_
typedef ImBitmapFont* ImFont;
struct ImGuiTextEditCallbackData;
struct ImVec2
{
@ -67,8 +62,17 @@ struct ImVec4
#endif
};
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.
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).
// this implementation does NOT call c++ constructors! we don't need them! also only provide the minimum functionalities we need.
// Use '#define ImVector std::vector' if you want to use the STL type or your own type.
// Our implementation does NOT call c++ constructors! because the data types we use don't need them (but that could be added as well). Only provide the minimum functionalities we need.
#ifndef ImVector
template<typename T>
class ImVector
@ -84,7 +88,7 @@ public:
typedef const value_type* const_iterator;
ImVector() { Size = Capacity = 0; Data = NULL; }
~ImVector() { if (Data) IM_FREE(Data); }
~ImVector() { if (Data) ImGui::MemFree(Data); }
inline bool empty() const { return Size == 0; }
inline size_t size() const { return Size; }
@ -95,7 +99,7 @@ public:
inline value_type& operator[](size_t i) { IM_ASSERT(i < Size); return Data[i]; }
inline const value_type& operator[](size_t i) const { IM_ASSERT(i < Size); return Data[i]; }
inline void clear() { if (Data) { Size = Capacity = 0; IM_FREE(Data); Data = NULL; } }
inline void clear() { if (Data) { Size = Capacity = 0; ImGui::MemFree(Data); Data = NULL; } }
inline iterator begin() { return Data; }
inline const_iterator begin() const { return Data; }
inline iterator end() { return Data + Size; }
@ -106,19 +110,19 @@ public:
inline const value_type& back() const { IM_ASSERT(Size > 0); return at(Size-1); }
inline void swap(ImVector<T>& rhs) { const size_t rhs_size = rhs.Size; rhs.Size = Size; Size = rhs_size; const size_t rhs_cap = rhs.Capacity; rhs.Capacity = Capacity; Capacity = rhs_cap; value_type* rhs_data = rhs.Data; rhs.Data = Data; Data = rhs_data; }
inline void reserve(size_t new_capacity) { Data = (value_type*)IM_REALLOC(Data, new_capacity * sizeof(value_type)); Capacity = new_capacity; }
inline void reserve(size_t new_capacity) { Data = (value_type*)ImGui::MemRealloc(Data, new_capacity * sizeof(value_type)); Capacity = new_capacity; }
inline void resize(size_t new_size) { if (new_size > Capacity) reserve(new_size); Size = new_size; }
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 int 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 int 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 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 - (size_t)off) * sizeof(value_type)); Data[off] = v; Size++; }
};
#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)
@ -130,145 +134,170 @@ public:
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);
void End();
void BeginChild(const char* str_id, ImVec2 size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0);
void EndChild();
bool GetWindowIsFocused();
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 GetWindowSize();
ImVec2 GetWindowContentRegionMin();
ImVec2 GetWindowContentRegionMax();
ImDrawList* GetWindowDrawList();
void SetFontScale(float scale);
void SetScrollPosHere();
void SetTreeStateStorage(ImGuiStorage* tree);
ImGuiStorage* GetTreeStateStorage();
void PushItemWidth(float item_width);
void PopItemWidth();
float GetItemWidth();
void PushAllowKeyboardFocus(bool v);
void PopAllowKeyboardFocus();
void PushStyleColor(ImGuiCol idx, const ImVec4& col);
void PopStyleColor();
IMGUI_API 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.
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 GetWindowSize();
IMGUI_API float GetWindowWidth();
IMGUI_API void SetWindowSize(const ImVec2& size); // set to ImVec2(0,0) to force an auto-fit
IMGUI_API ImVec2 GetWindowPos(); // you should rarely need/care about the window position, but it can be useful if you want to use your own drawing.
IMGUI_API void SetWindowPos(const ImVec2& pos); // set current window pos.
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 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 'offset' to access sub components of a multiple component widget.
IMGUI_API void SetTreeStateStorage(ImGuiStorage* tree); // replace tree state storage with our own (if you want to manipulate it yourself, typically clear subsection of it).
IMGUI_API ImGuiStorage* GetTreeStateStorage();
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 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 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 higher 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();
IMGUI_API void PushID(const char* str_id);
IMGUI_API void PushID(const void* ptr_id);
IMGUI_API void PushID(const int int_id);
IMGUI_API void PopID();
// 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 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 BulletText(const char* fmt, ...);
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);
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[3], 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 InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, int decimal_precision = -1);
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);
bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags 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 user is responsible for calling TreePop
bool TreeNode(const char* str_id, const char* fmt, ...); // "
bool TreeNode(const void* ptr_id, const char* fmt, ...); // "
void TreePush(const char* str_id = NULL); // already called by TreeNode(), but you can call Push/Pop yourself for layout 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 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);
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);
IMGUI_API void LogButtons();
IMGUI_API void LogToTTY(int max_depth = -1);
IMGUI_API void LogToFile(int max_depth = -1, const char* filename = NULL);
IMGUI_API void LogToClipboard(int max_depth = -1);
// 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 IsMouseHoveringBox(const ImVec2& box_min, const ImVec2& box_max);
ImVec2 GetMousePos();
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 void SetNewWindowDefaultPos(const ImVec2& pos); // set position of window that do
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* GetStyleColorName(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 = true, float wrap_width = -1.0f);
}; // namespace ImGui
} // namespace ImGui
// Flags for ImGui::Begin()
enum ImGuiWindowFlags_
@ -279,21 +308,26 @@ 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_AlwaysAutoResize = 1 << 5,
ImGuiWindowFlags_ChildWindow = 1 << 6, // For internal use by BeginChild()
ImGuiWindowFlags_ChildWindowAutoFitX = 1 << 7, // For internal use by BeginChild()
ImGuiWindowFlags_ChildWindowAutoFitY = 1 << 8, // For internal use by BeginChild()
ImGuiWindowFlags_ComboBox = 1 << 9, // For internal use by ComboBox()
ImGuiWindowFlags_Tooltip = 1 << 10 // For internal use by Render() when using Tooltip
};
// Flags for ImGui::InputText()
enum ImGuiInputTextFlags_
{
// Default: 0
ImGuiInputTextFlags_CharsDecimal = 1 << 0,
ImGuiInputTextFlags_CharsHexadecimal = 1 << 1,
ImGuiInputTextFlags_AutoSelectAll = 1 << 2,
ImGuiInputTextFlags_AlignCenter = 1 << 3,
ImGuiInputTextFlags_CharsDecimal = 1 << 0, // Allow 0123456789.+-*/
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_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 frame
//ImGuiInputTextFlags_AlignCenter = 1 << 6,
};
// User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array
@ -316,9 +350,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,
@ -358,15 +393,29 @@ 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_FramePadding, // ImVec2
ImGuiStyleVar_ItemSpacing, // ImVec2
ImGuiStyleVar_ItemInnerSpacing, // ImVec2
ImGuiStyleVar_TreeNodeSpacing, // float
ImGuiStyleVar_ColumnsMinSpacing // float
};
// Enumeration for ColorEditMode()
enum ImGuiColorEditMode_
{
ImGuiColorEditMode_UserSelect = -1,
ImGuiColorEditMode_RGB = 0,
ImGuiColorEditMode_HSV = 1,
ImGuiColorEditMode_HEX = 2,
ImGuiColorEditMode_HEX = 2
};
struct ImGuiStyle
@ -386,14 +435,17 @@ struct ImGuiStyle
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.
// Read 'Programmer guide' section in .cpp file for general usage.
struct ImGuiIO
{
//------------------------------------------------------------------
// Settings (fill once) // Default value:
//------------------------------------------------------------------
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.
@ -402,40 +454,60 @@ struct ImGuiIO
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.
bool FontAllowScaling; // = false // Set to allow scaling text with CTRL+Wheel.
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
// Settings - Rendering function (REQUIRED)
void* UserData; // = NULL // Store your own data for retrieval by callbacks.
//------------------------------------------------------------------
// User Functions
//------------------------------------------------------------------
// REQUIRED: rendering function.
// See example code if you are unsure of how to implement this.
void (*RenderDrawListsFn)(ImDrawList** const draw_lists, int count);
void (*RenderDrawListsFn)(ImDrawList** const draw_lists, int count);
// Settings - Clipboard Support
// Override to provide your clipboard handlers.
// On Windows architecture, defaults to use the native Win32 clipboard, otherwise default to use a ImGui private clipboard.
// NB- for SetClipboardTextFn, the string is *NOT* zero-terminated at 'text_end'
const char* (*GetClipboardTextFn)();
void (*SetClipboardTextFn)(const char* text, const char* text_end);
// Optional: access OS clipboard (default to use native Win32 clipboard on Windows, otherwise use a ImGui private clipboard)
// Override to access OS clipboard on other architectures.
const char* (*GetClipboardTextFn)();
void (*SetClipboardTextFn)(const char* text);
// Optional: override memory allocations (default to posix malloc/realloc/free)
void* (*MemAllocFn)(size_t sz);
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)
void (*ImeSetInputScreenPosFn)(int x, int y);
//------------------------------------------------------------------
// Input - Fill before calling NewFrame()
//------------------------------------------------------------------
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)
char InputCharacters[16]; // List of characters input (translated by user from keypress+keyboard state). Fill using AddInputCharacter() helper.
// Output - Retrieve after calling NewFrame(), you can use them to discard inputs or hide them from the rest of your application
bool WantCaptureMouse; // ImGui is using your mouse input (= window is being hovered or widget is active).
bool WantCaptureKeyboard; // imGui is using your keyboard input (= widget is active).
ImWchar InputCharacters[16+1]; // List of characters input (translated by user from keypress+keyboard state). Fill using AddInputCharacter() helper.
// Function
void AddInputCharacter(char c); // 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
//------------------------------------------------------------------
bool WantCaptureMouse; // Mouse is hovering a window or widget is active (= ImGui will use your mouse input)
bool WantCaptureKeyboard; // Widget is active (= ImGui will use your keyboard input)
//------------------------------------------------------------------
// [Internal] ImGui will maintain those fields for you
//------------------------------------------------------------------
ImVec2 MousePosPrev;
ImVec2 MouseDelta;
bool MouseClicked[5];
@ -445,7 +517,7 @@ struct ImGuiIO
float MouseDownTime[5];
float KeysDownTime[512];
ImGuiIO();
IMGUI_API ImGuiIO();
};
//-----------------------------------------------------------------------------
@ -453,23 +525,27 @@ 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]"
struct ImGuiTextFilter
{
struct TextRange
{
const char* b;
struct TextRange
{
const char* b;
const char* e;
TextRange() { b = e = NULL; }
@ -478,9 +554,9 @@ struct ImGuiTextFilter
const char* end() const { return e; }
bool empty() const { return b == e; }
char front() const { return *b; }
static bool isblank(char c) { return c == ' ' || c == '\t'; }
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];
@ -492,7 +568,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
@ -501,12 +577,13 @@ 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, ...);
};
// Helper: Key->value storage
@ -517,15 +594,33 @@ struct ImGuiTextBuffer
struct ImGuiStorage
{
struct Pair { ImU32 key; int val; };
ImVector<Pair> Data;
ImVector<Pair> Data;
void Clear();
int GetInt(ImU32 key, int default_val = 0);
void SetInt(ImU32 key, int val);
void SetAllInt(int val);
IMGUI_API void Clear();
IMGUI_API int GetInt(ImU32 key, int default_val = 0);
IMGUI_API void SetInt(ImU32 key, int val);
IMGUI_API void SetAllInt(int val);
int* Find(ImU32 key);
void Insert(ImU32 key, int val);
IMGUI_API int* Find(ImU32 key);
IMGUI_API 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);
};
//-----------------------------------------------------------------------------
@ -539,16 +634,27 @@ struct ImDrawCmd
ImVec4 clip_rect;
};
// sizeof() == 20
#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.
// 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
// User is responsible for providing a renderer for this in ImGuiIO::RenderDrawListFn
// 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.
// 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
struct ImDrawList
{
// This is what you have to render
@ -561,34 +667,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
// 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
{
@ -598,15 +746,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;
@ -616,8 +762,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;
@ -631,31 +776,4 @@ 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 CalcTextSize(float size, float max_width, const char* text_begin, const char* text_end, const char** remaining = NULL) const;
void RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, ImDrawVert*& out_vertices) const;
};

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

BIN
web/utf8_sample_01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB