diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore
new file mode 100644
index 0000000..8feda89
--- /dev/null
+++ b/examples/apple_example/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+imguiex.xcodeproj/project.xcworkspace/
+imguiex.xcodeproj/xcuserdata/
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore
new file mode 100644
index 0000000..8feda89
--- /dev/null
+++ b/examples/apple_example/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+imguiex.xcodeproj/project.xcworkspace/
+imguiex.xcodeproj/xcuserdata/
\ No newline at end of file
diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md
new file mode 100644
index 0000000..339f6bf
--- /dev/null
+++ b/examples/apple_example/README.md
@@ -0,0 +1,41 @@
+# iOS / OSX example
+
+## Introduction
+
+This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device.
+
+It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy.
+
+Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active.
+
+## How to Use on iOS
+
+* In Synergy, go to Preferences, and uncheck "Use SSL encryption"
+* Run the example app.
+* Tap the "servername" button in the corner
+* Enter the name or the IP of your synergy host
+* If you had previously connected to a server, you may need to kill and re-start the app.
+
+## How to Build on OSX
+
+* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh)
+* Run the command: `brew install glfw3`
+* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme
+* Click `Run` button
+
+## Notes and TODOs
+
+Things that would be nice but I didn't get around to doing:
+
+* iOS software keyboard not supported for text inputs
+* iOS hardware (bluetooth) keyboards not supported
+* Graceful disconnect/reconnect from uSynergy.
+* Copy/Paste not well-supported
+
+## C++ on iOS / OSX
+
+ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension.
+
+Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer.
+
+In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly.
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore
new file mode 100644
index 0000000..8feda89
--- /dev/null
+++ b/examples/apple_example/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+imguiex.xcodeproj/project.xcworkspace/
+imguiex.xcodeproj/xcuserdata/
\ No newline at end of file
diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md
new file mode 100644
index 0000000..339f6bf
--- /dev/null
+++ b/examples/apple_example/README.md
@@ -0,0 +1,41 @@
+# iOS / OSX example
+
+## Introduction
+
+This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device.
+
+It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy.
+
+Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active.
+
+## How to Use on iOS
+
+* In Synergy, go to Preferences, and uncheck "Use SSL encryption"
+* Run the example app.
+* Tap the "servername" button in the corner
+* Enter the name or the IP of your synergy host
+* If you had previously connected to a server, you may need to kill and re-start the app.
+
+## How to Build on OSX
+
+* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh)
+* Run the command: `brew install glfw3`
+* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme
+* Click `Run` button
+
+## Notes and TODOs
+
+Things that would be nice but I didn't get around to doing:
+
+* iOS software keyboard not supported for text inputs
+* iOS hardware (bluetooth) keyboards not supported
+* Graceful disconnect/reconnect from uSynergy.
+* Copy/Paste not well-supported
+
+## C++ on iOS / OSX
+
+ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension.
+
+Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer.
+
+In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly.
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h
new file mode 100644
index 0000000..82f1542
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.h
@@ -0,0 +1,13 @@
+//
+// AppDelegate.h
+// imguiex
+
+#import
+
+@interface AppDelegate : UIResponder
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore
new file mode 100644
index 0000000..8feda89
--- /dev/null
+++ b/examples/apple_example/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+imguiex.xcodeproj/project.xcworkspace/
+imguiex.xcodeproj/xcuserdata/
\ No newline at end of file
diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md
new file mode 100644
index 0000000..339f6bf
--- /dev/null
+++ b/examples/apple_example/README.md
@@ -0,0 +1,41 @@
+# iOS / OSX example
+
+## Introduction
+
+This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device.
+
+It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy.
+
+Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active.
+
+## How to Use on iOS
+
+* In Synergy, go to Preferences, and uncheck "Use SSL encryption"
+* Run the example app.
+* Tap the "servername" button in the corner
+* Enter the name or the IP of your synergy host
+* If you had previously connected to a server, you may need to kill and re-start the app.
+
+## How to Build on OSX
+
+* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh)
+* Run the command: `brew install glfw3`
+* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme
+* Click `Run` button
+
+## Notes and TODOs
+
+Things that would be nice but I didn't get around to doing:
+
+* iOS software keyboard not supported for text inputs
+* iOS hardware (bluetooth) keyboards not supported
+* Graceful disconnect/reconnect from uSynergy.
+* Copy/Paste not well-supported
+
+## C++ on iOS / OSX
+
+ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension.
+
+Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer.
+
+In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly.
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h
new file mode 100644
index 0000000..82f1542
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.h
@@ -0,0 +1,13 @@
+//
+// AppDelegate.h
+// imguiex
+
+#import
+
+@interface AppDelegate : UIResponder
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m
new file mode 100644
index 0000000..ab83101
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.m
@@ -0,0 +1,41 @@
+//
+// AppDelegate.m
+// imguiex
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Override point for customization after application launch.
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore
new file mode 100644
index 0000000..8feda89
--- /dev/null
+++ b/examples/apple_example/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+imguiex.xcodeproj/project.xcworkspace/
+imguiex.xcodeproj/xcuserdata/
\ No newline at end of file
diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md
new file mode 100644
index 0000000..339f6bf
--- /dev/null
+++ b/examples/apple_example/README.md
@@ -0,0 +1,41 @@
+# iOS / OSX example
+
+## Introduction
+
+This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device.
+
+It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy.
+
+Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active.
+
+## How to Use on iOS
+
+* In Synergy, go to Preferences, and uncheck "Use SSL encryption"
+* Run the example app.
+* Tap the "servername" button in the corner
+* Enter the name or the IP of your synergy host
+* If you had previously connected to a server, you may need to kill and re-start the app.
+
+## How to Build on OSX
+
+* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh)
+* Run the command: `brew install glfw3`
+* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme
+* Click `Run` button
+
+## Notes and TODOs
+
+Things that would be nice but I didn't get around to doing:
+
+* iOS software keyboard not supported for text inputs
+* iOS hardware (bluetooth) keyboards not supported
+* Graceful disconnect/reconnect from uSynergy.
+* Copy/Paste not well-supported
+
+## C++ on iOS / OSX
+
+ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension.
+
+Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer.
+
+In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly.
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h
new file mode 100644
index 0000000..82f1542
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.h
@@ -0,0 +1,13 @@
+//
+// AppDelegate.h
+// imguiex
+
+#import
+
+@interface AppDelegate : UIResponder
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m
new file mode 100644
index 0000000..ab83101
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.m
@@ -0,0 +1,41 @@
+//
+// AppDelegate.m
+// imguiex
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Override point for customization after application launch.
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
new file mode 100644
index 0000000..5717c00
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore
new file mode 100644
index 0000000..8feda89
--- /dev/null
+++ b/examples/apple_example/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+imguiex.xcodeproj/project.xcworkspace/
+imguiex.xcodeproj/xcuserdata/
\ No newline at end of file
diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md
new file mode 100644
index 0000000..339f6bf
--- /dev/null
+++ b/examples/apple_example/README.md
@@ -0,0 +1,41 @@
+# iOS / OSX example
+
+## Introduction
+
+This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device.
+
+It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy.
+
+Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active.
+
+## How to Use on iOS
+
+* In Synergy, go to Preferences, and uncheck "Use SSL encryption"
+* Run the example app.
+* Tap the "servername" button in the corner
+* Enter the name or the IP of your synergy host
+* If you had previously connected to a server, you may need to kill and re-start the app.
+
+## How to Build on OSX
+
+* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh)
+* Run the command: `brew install glfw3`
+* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme
+* Click `Run` button
+
+## Notes and TODOs
+
+Things that would be nice but I didn't get around to doing:
+
+* iOS software keyboard not supported for text inputs
+* iOS hardware (bluetooth) keyboards not supported
+* Graceful disconnect/reconnect from uSynergy.
+* Copy/Paste not well-supported
+
+## C++ on iOS / OSX
+
+ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension.
+
+Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer.
+
+In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly.
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h
new file mode 100644
index 0000000..82f1542
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.h
@@ -0,0 +1,13 @@
+//
+// AppDelegate.h
+// imguiex
+
+#import
+
+@interface AppDelegate : UIResponder
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m
new file mode 100644
index 0000000..ab83101
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.m
@@ -0,0 +1,41 @@
+//
+// AppDelegate.m
+// imguiex
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Override point for customization after application launch.
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
new file mode 100644
index 0000000..5717c00
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..90dfb2e
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore
new file mode 100644
index 0000000..8feda89
--- /dev/null
+++ b/examples/apple_example/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+imguiex.xcodeproj/project.xcworkspace/
+imguiex.xcodeproj/xcuserdata/
\ No newline at end of file
diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md
new file mode 100644
index 0000000..339f6bf
--- /dev/null
+++ b/examples/apple_example/README.md
@@ -0,0 +1,41 @@
+# iOS / OSX example
+
+## Introduction
+
+This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device.
+
+It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy.
+
+Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active.
+
+## How to Use on iOS
+
+* In Synergy, go to Preferences, and uncheck "Use SSL encryption"
+* Run the example app.
+* Tap the "servername" button in the corner
+* Enter the name or the IP of your synergy host
+* If you had previously connected to a server, you may need to kill and re-start the app.
+
+## How to Build on OSX
+
+* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh)
+* Run the command: `brew install glfw3`
+* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme
+* Click `Run` button
+
+## Notes and TODOs
+
+Things that would be nice but I didn't get around to doing:
+
+* iOS software keyboard not supported for text inputs
+* iOS hardware (bluetooth) keyboards not supported
+* Graceful disconnect/reconnect from uSynergy.
+* Copy/Paste not well-supported
+
+## C++ on iOS / OSX
+
+ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension.
+
+Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer.
+
+In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly.
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h
new file mode 100644
index 0000000..82f1542
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.h
@@ -0,0 +1,13 @@
+//
+// AppDelegate.h
+// imguiex
+
+#import
+
+@interface AppDelegate : UIResponder
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m
new file mode 100644
index 0000000..ab83101
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.m
@@ -0,0 +1,41 @@
+//
+// AppDelegate.m
+// imguiex
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Override point for customization after application launch.
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
new file mode 100644
index 0000000..5717c00
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..90dfb2e
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h
new file mode 100644
index 0000000..3323cfd
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.h
@@ -0,0 +1,12 @@
+//
+// GameViewController.h
+// imguiex
+
+// This is the OpenGL Example template from XCode, modified to support ImGui
+
+#import
+#import
+
+@interface GameViewController : GLKViewController
+
+@end
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore
new file mode 100644
index 0000000..8feda89
--- /dev/null
+++ b/examples/apple_example/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+imguiex.xcodeproj/project.xcworkspace/
+imguiex.xcodeproj/xcuserdata/
\ No newline at end of file
diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md
new file mode 100644
index 0000000..339f6bf
--- /dev/null
+++ b/examples/apple_example/README.md
@@ -0,0 +1,41 @@
+# iOS / OSX example
+
+## Introduction
+
+This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device.
+
+It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy.
+
+Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active.
+
+## How to Use on iOS
+
+* In Synergy, go to Preferences, and uncheck "Use SSL encryption"
+* Run the example app.
+* Tap the "servername" button in the corner
+* Enter the name or the IP of your synergy host
+* If you had previously connected to a server, you may need to kill and re-start the app.
+
+## How to Build on OSX
+
+* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh)
+* Run the command: `brew install glfw3`
+* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme
+* Click `Run` button
+
+## Notes and TODOs
+
+Things that would be nice but I didn't get around to doing:
+
+* iOS software keyboard not supported for text inputs
+* iOS hardware (bluetooth) keyboards not supported
+* Graceful disconnect/reconnect from uSynergy.
+* Copy/Paste not well-supported
+
+## C++ on iOS / OSX
+
+ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension.
+
+Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer.
+
+In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly.
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h
new file mode 100644
index 0000000..82f1542
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.h
@@ -0,0 +1,13 @@
+//
+// AppDelegate.h
+// imguiex
+
+#import
+
+@interface AppDelegate : UIResponder
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m
new file mode 100644
index 0000000..ab83101
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.m
@@ -0,0 +1,41 @@
+//
+// AppDelegate.m
+// imguiex
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Override point for customization after application launch.
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
new file mode 100644
index 0000000..5717c00
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..90dfb2e
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h
new file mode 100644
index 0000000..3323cfd
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.h
@@ -0,0 +1,12 @@
+//
+// GameViewController.h
+// imguiex
+
+// This is the OpenGL Example template from XCode, modified to support ImGui
+
+#import
+#import
+
+@interface GameViewController : GLKViewController
+
+@end
diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m
new file mode 100644
index 0000000..e902f7a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.m
@@ -0,0 +1,481 @@
+//
+// GameViewController.m
+// imguiex
+//
+#import "GameViewController.h"
+#import
+
+#import "imgui_impl_ios.h"
+#import "debug_hud.h"
+
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
+
+#define SERVERNAME_KEY @"ServerName"
+
+#define SERVERNAME_ALERT_TAG (10)
+
+// Uniform index.
+enum
+{
+ UNIFORM_MODELVIEWPROJECTION_MATRIX,
+ UNIFORM_NORMAL_MATRIX,
+ UNIFORM_DIFFUSE_COLOR,
+
+ NUM_UNIFORMS
+};
+GLint uniforms[NUM_UNIFORMS];
+
+// Attribute index.
+enum
+{
+ ATTRIB_VERTEX,
+ ATTRIB_NORMAL,
+ NUM_ATTRIBUTES
+};
+
+GLfloat gCubeVertexData[216] =
+{
+ // Data layout for each line below is:
+ // positionX, positionY, positionZ, normalX, normalY, normalZ,
+ 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+
+ 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+
+ -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+
+ -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+
+ 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+
+ 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f
+};
+
+@interface GameViewController ()
+{
+ GLuint _program;
+
+ GLKMatrix4 _modelViewProjectionMatrix;
+ GLKMatrix3 _normalMatrix;
+ float _rotation;
+
+ GLuint _vertexArray;
+ GLuint _vertexBuffer;
+
+ DebugHUD _hud;
+}
+@property (strong, nonatomic) EAGLContext *context;
+@property (strong, nonatomic) GLKBaseEffect *effect;
+@property (strong, nonatomic) ImGuiHelper *imgui;
+@property (weak, nonatomic) IBOutlet UIButton *btnServername;
+
+@property (strong, nonatomic) NSString *serverName;
+
+- (IBAction)onServernameTapped:(id)sender;
+
+- (void)setupGL;
+- (void)tearDownGL;
+
+- (BOOL)loadShaders;
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file;
+- (BOOL)linkProgram:(GLuint)prog;
+- (BOOL)validateProgram:(GLuint)prog;
+@end
+
+@implementation GameViewController
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+
+ if (!self.context) {
+ NSLog(@"Failed to create ES context");
+ }
+
+ GLKView *view = (GLKView *)self.view;
+ view.context = self.context;
+ view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
+
+ [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
+
+ [self setupGL];
+
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ];
+ self.imgui = [[ImGuiHelper alloc] initWithView:self.view ];
+ if (self.serverName)
+ {
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+ [self.imgui connectServer: self.serverName ];
+ }
+
+ DebugHUD_InitDefaults( &_hud );
+}
+
+- (void)dealloc
+{
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+
+ if ([self isViewLoaded] && ([[self view] window] == nil)) {
+ self.view = nil;
+
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+ self.context = nil;
+ }
+
+ // Dispose of any resources that can be recreated.
+}
+
+
+- (BOOL)prefersStatusBarHidden {
+ return YES;
+}
+
+- (IBAction)onServernameTapped:(id)sender
+{
+ UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ];
+ alert.alertViewStyle = UIAlertViewStylePlainTextInput;
+ alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to
+ [alert show];
+}
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG))
+ {
+ // This is really janky. I usually just hardcode the servername since I'm building it anyway.
+ // If you want to properly handle updating the server, you'll want to tear down and recreate
+ // the usynergy stuff in connectServer
+ BOOL serverNameWasSet = self.serverName.length > 0;
+ NSString *serverName = [[alertView textFieldAtIndex:0] text];
+
+ if ([serverName length] > 0) {
+ self.serverName = serverName;
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ [userDefaults setObject:serverName forKey:SERVERNAME_KEY ];
+ [userDefaults synchronize];
+
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+
+ // If we hadn't previously connected, try now
+ if (!serverNameWasSet) {
+ [self.imgui connectServer:self.serverName];
+ }
+ else
+ {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated"
+ message:@"Restart the app to connect the server"
+ delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
+ [alert show];
+ }
+ }
+ }
+}
+
+- (void)setupGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ [self loadShaders];
+
+ self.effect = [[GLKBaseEffect alloc] init];
+ self.effect.light0.enabled = GL_TRUE;
+ self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f);
+
+ glEnable(GL_DEPTH_TEST);
+
+ glGenVertexArraysOES(1, &_vertexArray);
+ glBindVertexArrayOES(_vertexArray);
+
+ glGenBuffers(1, &_vertexBuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);
+
+ glEnableVertexAttribArray(GLKVertexAttribPosition);
+ glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
+ glEnableVertexAttribArray(GLKVertexAttribNormal);
+ glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
+
+ glBindVertexArrayOES(0);
+
+
+}
+
+- (void)tearDownGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ glDeleteBuffers(1, &_vertexBuffer);
+ glDeleteVertexArraysOES(1, &_vertexArray);
+
+ self.effect = nil;
+
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+}
+
+#pragma mark - GLKView and GLKViewController delegate methods
+
+- (void)update
+{
+ float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height);
+ GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
+
+ self.effect.transform.projectionMatrix = projectionMatrix;
+
+ GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);
+ baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
+
+ // Compute the model view matrix for the object rendered with GLKit
+ GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ self.effect.transform.modelviewMatrix = modelViewMatrix;
+
+ // Compute the model view matrix for the object rendered with ES2
+ modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
+
+ _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
+
+ _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0));
+}
+
+
+- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
+{
+ glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glBindVertexArrayOES(_vertexArray);
+
+ // Render the object with GLKit
+ [self.effect prepareToDraw];
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ // Render the object again with ES2
+ glUseProgram(_program);
+
+ glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
+ glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
+ glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] );
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ [self.imgui newFrame];
+
+ // Now do our ImGUI UI
+ DebugHUD_DoInterface( &_hud );
+
+ self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f);
+
+ // Now render Imgui
+ [self.imgui render];
+
+}
+
+#pragma mark - OpenGL ES 2 shader compilation
+
+- (BOOL)loadShaders
+{
+ GLuint vertShader, fragShader;
+ NSString *vertShaderPathname, *fragShaderPathname;
+
+ // Create shader program.
+ _program = glCreateProgram();
+
+ // Create and compile vertex shader.
+ vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
+ if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
+ NSLog(@"Failed to compile vertex shader");
+ return NO;
+ }
+
+ // Create and compile fragment shader.
+ fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
+ if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
+ NSLog(@"Failed to compile fragment shader");
+ return NO;
+ }
+
+ // Attach vertex shader to program.
+ glAttachShader(_program, vertShader);
+
+ // Attach fragment shader to program.
+ glAttachShader(_program, fragShader);
+
+ // Bind attribute locations.
+ // This needs to be done prior to linking.
+ glBindAttribLocation(_program, GLKVertexAttribPosition, "position");
+ glBindAttribLocation(_program, GLKVertexAttribNormal, "normal");
+
+ // Link program.
+ if (![self linkProgram:_program]) {
+ NSLog(@"Failed to link program: %d", _program);
+
+ if (vertShader) {
+ glDeleteShader(vertShader);
+ vertShader = 0;
+ }
+ if (fragShader) {
+ glDeleteShader(fragShader);
+ fragShader = 0;
+ }
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+
+ return NO;
+ }
+
+ // Get uniform locations.
+ uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix");
+ uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix");
+ uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor");
+
+ // Release vertex and fragment shaders.
+ if (vertShader) {
+ glDetachShader(_program, vertShader);
+ glDeleteShader(vertShader);
+ }
+ if (fragShader) {
+ glDetachShader(_program, fragShader);
+ glDeleteShader(fragShader);
+ }
+
+ return YES;
+}
+
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
+{
+ GLint status;
+ const GLchar *source;
+
+ source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
+ if (!source) {
+ NSLog(@"Failed to load vertex shader");
+ return NO;
+ }
+
+ *shader = glCreateShader(type);
+ glShaderSource(*shader, 1, &source, NULL);
+ glCompileShader(*shader);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(*shader, logLength, &logLength, log);
+ NSLog(@"Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
+ if (status == 0) {
+ glDeleteShader(*shader);
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)linkProgram:(GLuint)prog
+{
+ GLint status;
+ glLinkProgram(prog);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program link log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetProgramiv(prog, GL_LINK_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)validateProgram:(GLuint)prog
+{
+ GLint logLength, status;
+
+ glValidateProgram(prog);
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program validate log:\n%s", log);
+ free(log);
+ }
+
+ glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+@end
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore
new file mode 100644
index 0000000..8feda89
--- /dev/null
+++ b/examples/apple_example/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+imguiex.xcodeproj/project.xcworkspace/
+imguiex.xcodeproj/xcuserdata/
\ No newline at end of file
diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md
new file mode 100644
index 0000000..339f6bf
--- /dev/null
+++ b/examples/apple_example/README.md
@@ -0,0 +1,41 @@
+# iOS / OSX example
+
+## Introduction
+
+This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device.
+
+It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy.
+
+Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active.
+
+## How to Use on iOS
+
+* In Synergy, go to Preferences, and uncheck "Use SSL encryption"
+* Run the example app.
+* Tap the "servername" button in the corner
+* Enter the name or the IP of your synergy host
+* If you had previously connected to a server, you may need to kill and re-start the app.
+
+## How to Build on OSX
+
+* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh)
+* Run the command: `brew install glfw3`
+* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme
+* Click `Run` button
+
+## Notes and TODOs
+
+Things that would be nice but I didn't get around to doing:
+
+* iOS software keyboard not supported for text inputs
+* iOS hardware (bluetooth) keyboards not supported
+* Graceful disconnect/reconnect from uSynergy.
+* Copy/Paste not well-supported
+
+## C++ on iOS / OSX
+
+ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension.
+
+Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer.
+
+In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly.
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h
new file mode 100644
index 0000000..82f1542
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.h
@@ -0,0 +1,13 @@
+//
+// AppDelegate.h
+// imguiex
+
+#import
+
+@interface AppDelegate : UIResponder
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m
new file mode 100644
index 0000000..ab83101
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.m
@@ -0,0 +1,41 @@
+//
+// AppDelegate.m
+// imguiex
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Override point for customization after application launch.
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
new file mode 100644
index 0000000..5717c00
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..90dfb2e
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h
new file mode 100644
index 0000000..3323cfd
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.h
@@ -0,0 +1,12 @@
+//
+// GameViewController.h
+// imguiex
+
+// This is the OpenGL Example template from XCode, modified to support ImGui
+
+#import
+#import
+
+@interface GameViewController : GLKViewController
+
+@end
diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m
new file mode 100644
index 0000000..e902f7a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.m
@@ -0,0 +1,481 @@
+//
+// GameViewController.m
+// imguiex
+//
+#import "GameViewController.h"
+#import
+
+#import "imgui_impl_ios.h"
+#import "debug_hud.h"
+
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
+
+#define SERVERNAME_KEY @"ServerName"
+
+#define SERVERNAME_ALERT_TAG (10)
+
+// Uniform index.
+enum
+{
+ UNIFORM_MODELVIEWPROJECTION_MATRIX,
+ UNIFORM_NORMAL_MATRIX,
+ UNIFORM_DIFFUSE_COLOR,
+
+ NUM_UNIFORMS
+};
+GLint uniforms[NUM_UNIFORMS];
+
+// Attribute index.
+enum
+{
+ ATTRIB_VERTEX,
+ ATTRIB_NORMAL,
+ NUM_ATTRIBUTES
+};
+
+GLfloat gCubeVertexData[216] =
+{
+ // Data layout for each line below is:
+ // positionX, positionY, positionZ, normalX, normalY, normalZ,
+ 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+
+ 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+
+ -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+
+ -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+
+ 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+
+ 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f
+};
+
+@interface GameViewController ()
+{
+ GLuint _program;
+
+ GLKMatrix4 _modelViewProjectionMatrix;
+ GLKMatrix3 _normalMatrix;
+ float _rotation;
+
+ GLuint _vertexArray;
+ GLuint _vertexBuffer;
+
+ DebugHUD _hud;
+}
+@property (strong, nonatomic) EAGLContext *context;
+@property (strong, nonatomic) GLKBaseEffect *effect;
+@property (strong, nonatomic) ImGuiHelper *imgui;
+@property (weak, nonatomic) IBOutlet UIButton *btnServername;
+
+@property (strong, nonatomic) NSString *serverName;
+
+- (IBAction)onServernameTapped:(id)sender;
+
+- (void)setupGL;
+- (void)tearDownGL;
+
+- (BOOL)loadShaders;
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file;
+- (BOOL)linkProgram:(GLuint)prog;
+- (BOOL)validateProgram:(GLuint)prog;
+@end
+
+@implementation GameViewController
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+
+ if (!self.context) {
+ NSLog(@"Failed to create ES context");
+ }
+
+ GLKView *view = (GLKView *)self.view;
+ view.context = self.context;
+ view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
+
+ [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
+
+ [self setupGL];
+
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ];
+ self.imgui = [[ImGuiHelper alloc] initWithView:self.view ];
+ if (self.serverName)
+ {
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+ [self.imgui connectServer: self.serverName ];
+ }
+
+ DebugHUD_InitDefaults( &_hud );
+}
+
+- (void)dealloc
+{
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+
+ if ([self isViewLoaded] && ([[self view] window] == nil)) {
+ self.view = nil;
+
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+ self.context = nil;
+ }
+
+ // Dispose of any resources that can be recreated.
+}
+
+
+- (BOOL)prefersStatusBarHidden {
+ return YES;
+}
+
+- (IBAction)onServernameTapped:(id)sender
+{
+ UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ];
+ alert.alertViewStyle = UIAlertViewStylePlainTextInput;
+ alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to
+ [alert show];
+}
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG))
+ {
+ // This is really janky. I usually just hardcode the servername since I'm building it anyway.
+ // If you want to properly handle updating the server, you'll want to tear down and recreate
+ // the usynergy stuff in connectServer
+ BOOL serverNameWasSet = self.serverName.length > 0;
+ NSString *serverName = [[alertView textFieldAtIndex:0] text];
+
+ if ([serverName length] > 0) {
+ self.serverName = serverName;
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ [userDefaults setObject:serverName forKey:SERVERNAME_KEY ];
+ [userDefaults synchronize];
+
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+
+ // If we hadn't previously connected, try now
+ if (!serverNameWasSet) {
+ [self.imgui connectServer:self.serverName];
+ }
+ else
+ {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated"
+ message:@"Restart the app to connect the server"
+ delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
+ [alert show];
+ }
+ }
+ }
+}
+
+- (void)setupGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ [self loadShaders];
+
+ self.effect = [[GLKBaseEffect alloc] init];
+ self.effect.light0.enabled = GL_TRUE;
+ self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f);
+
+ glEnable(GL_DEPTH_TEST);
+
+ glGenVertexArraysOES(1, &_vertexArray);
+ glBindVertexArrayOES(_vertexArray);
+
+ glGenBuffers(1, &_vertexBuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);
+
+ glEnableVertexAttribArray(GLKVertexAttribPosition);
+ glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
+ glEnableVertexAttribArray(GLKVertexAttribNormal);
+ glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
+
+ glBindVertexArrayOES(0);
+
+
+}
+
+- (void)tearDownGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ glDeleteBuffers(1, &_vertexBuffer);
+ glDeleteVertexArraysOES(1, &_vertexArray);
+
+ self.effect = nil;
+
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+}
+
+#pragma mark - GLKView and GLKViewController delegate methods
+
+- (void)update
+{
+ float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height);
+ GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
+
+ self.effect.transform.projectionMatrix = projectionMatrix;
+
+ GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);
+ baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
+
+ // Compute the model view matrix for the object rendered with GLKit
+ GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ self.effect.transform.modelviewMatrix = modelViewMatrix;
+
+ // Compute the model view matrix for the object rendered with ES2
+ modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
+
+ _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
+
+ _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0));
+}
+
+
+- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
+{
+ glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glBindVertexArrayOES(_vertexArray);
+
+ // Render the object with GLKit
+ [self.effect prepareToDraw];
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ // Render the object again with ES2
+ glUseProgram(_program);
+
+ glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
+ glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
+ glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] );
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ [self.imgui newFrame];
+
+ // Now do our ImGUI UI
+ DebugHUD_DoInterface( &_hud );
+
+ self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f);
+
+ // Now render Imgui
+ [self.imgui render];
+
+}
+
+#pragma mark - OpenGL ES 2 shader compilation
+
+- (BOOL)loadShaders
+{
+ GLuint vertShader, fragShader;
+ NSString *vertShaderPathname, *fragShaderPathname;
+
+ // Create shader program.
+ _program = glCreateProgram();
+
+ // Create and compile vertex shader.
+ vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
+ if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
+ NSLog(@"Failed to compile vertex shader");
+ return NO;
+ }
+
+ // Create and compile fragment shader.
+ fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
+ if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
+ NSLog(@"Failed to compile fragment shader");
+ return NO;
+ }
+
+ // Attach vertex shader to program.
+ glAttachShader(_program, vertShader);
+
+ // Attach fragment shader to program.
+ glAttachShader(_program, fragShader);
+
+ // Bind attribute locations.
+ // This needs to be done prior to linking.
+ glBindAttribLocation(_program, GLKVertexAttribPosition, "position");
+ glBindAttribLocation(_program, GLKVertexAttribNormal, "normal");
+
+ // Link program.
+ if (![self linkProgram:_program]) {
+ NSLog(@"Failed to link program: %d", _program);
+
+ if (vertShader) {
+ glDeleteShader(vertShader);
+ vertShader = 0;
+ }
+ if (fragShader) {
+ glDeleteShader(fragShader);
+ fragShader = 0;
+ }
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+
+ return NO;
+ }
+
+ // Get uniform locations.
+ uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix");
+ uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix");
+ uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor");
+
+ // Release vertex and fragment shaders.
+ if (vertShader) {
+ glDetachShader(_program, vertShader);
+ glDeleteShader(vertShader);
+ }
+ if (fragShader) {
+ glDetachShader(_program, fragShader);
+ glDeleteShader(fragShader);
+ }
+
+ return YES;
+}
+
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
+{
+ GLint status;
+ const GLchar *source;
+
+ source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
+ if (!source) {
+ NSLog(@"Failed to load vertex shader");
+ return NO;
+ }
+
+ *shader = glCreateShader(type);
+ glShaderSource(*shader, 1, &source, NULL);
+ glCompileShader(*shader);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(*shader, logLength, &logLength, log);
+ NSLog(@"Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
+ if (status == 0) {
+ glDeleteShader(*shader);
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)linkProgram:(GLuint)prog
+{
+ GLint status;
+ glLinkProgram(prog);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program link log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetProgramiv(prog, GL_LINK_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)validateProgram:(GLuint)prog
+{
+ GLint logLength, status;
+
+ glValidateProgram(prog);
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program validate log:\n%s", log);
+ free(log);
+ }
+
+ glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..06b60d8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,77 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@2x~iphone.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@3x~iphone.png",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76~ipad.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76@2x~ipad.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "83.5x83.5",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore
new file mode 100644
index 0000000..8feda89
--- /dev/null
+++ b/examples/apple_example/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+imguiex.xcodeproj/project.xcworkspace/
+imguiex.xcodeproj/xcuserdata/
\ No newline at end of file
diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md
new file mode 100644
index 0000000..339f6bf
--- /dev/null
+++ b/examples/apple_example/README.md
@@ -0,0 +1,41 @@
+# iOS / OSX example
+
+## Introduction
+
+This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device.
+
+It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy.
+
+Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active.
+
+## How to Use on iOS
+
+* In Synergy, go to Preferences, and uncheck "Use SSL encryption"
+* Run the example app.
+* Tap the "servername" button in the corner
+* Enter the name or the IP of your synergy host
+* If you had previously connected to a server, you may need to kill and re-start the app.
+
+## How to Build on OSX
+
+* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh)
+* Run the command: `brew install glfw3`
+* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme
+* Click `Run` button
+
+## Notes and TODOs
+
+Things that would be nice but I didn't get around to doing:
+
+* iOS software keyboard not supported for text inputs
+* iOS hardware (bluetooth) keyboards not supported
+* Graceful disconnect/reconnect from uSynergy.
+* Copy/Paste not well-supported
+
+## C++ on iOS / OSX
+
+ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension.
+
+Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer.
+
+In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly.
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h
new file mode 100644
index 0000000..82f1542
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.h
@@ -0,0 +1,13 @@
+//
+// AppDelegate.h
+// imguiex
+
+#import
+
+@interface AppDelegate : UIResponder
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m
new file mode 100644
index 0000000..ab83101
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.m
@@ -0,0 +1,41 @@
+//
+// AppDelegate.m
+// imguiex
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Override point for customization after application launch.
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
new file mode 100644
index 0000000..5717c00
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..90dfb2e
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h
new file mode 100644
index 0000000..3323cfd
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.h
@@ -0,0 +1,12 @@
+//
+// GameViewController.h
+// imguiex
+
+// This is the OpenGL Example template from XCode, modified to support ImGui
+
+#import
+#import
+
+@interface GameViewController : GLKViewController
+
+@end
diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m
new file mode 100644
index 0000000..e902f7a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.m
@@ -0,0 +1,481 @@
+//
+// GameViewController.m
+// imguiex
+//
+#import "GameViewController.h"
+#import
+
+#import "imgui_impl_ios.h"
+#import "debug_hud.h"
+
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
+
+#define SERVERNAME_KEY @"ServerName"
+
+#define SERVERNAME_ALERT_TAG (10)
+
+// Uniform index.
+enum
+{
+ UNIFORM_MODELVIEWPROJECTION_MATRIX,
+ UNIFORM_NORMAL_MATRIX,
+ UNIFORM_DIFFUSE_COLOR,
+
+ NUM_UNIFORMS
+};
+GLint uniforms[NUM_UNIFORMS];
+
+// Attribute index.
+enum
+{
+ ATTRIB_VERTEX,
+ ATTRIB_NORMAL,
+ NUM_ATTRIBUTES
+};
+
+GLfloat gCubeVertexData[216] =
+{
+ // Data layout for each line below is:
+ // positionX, positionY, positionZ, normalX, normalY, normalZ,
+ 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+
+ 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+
+ -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+
+ -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+
+ 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+
+ 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f
+};
+
+@interface GameViewController ()
+{
+ GLuint _program;
+
+ GLKMatrix4 _modelViewProjectionMatrix;
+ GLKMatrix3 _normalMatrix;
+ float _rotation;
+
+ GLuint _vertexArray;
+ GLuint _vertexBuffer;
+
+ DebugHUD _hud;
+}
+@property (strong, nonatomic) EAGLContext *context;
+@property (strong, nonatomic) GLKBaseEffect *effect;
+@property (strong, nonatomic) ImGuiHelper *imgui;
+@property (weak, nonatomic) IBOutlet UIButton *btnServername;
+
+@property (strong, nonatomic) NSString *serverName;
+
+- (IBAction)onServernameTapped:(id)sender;
+
+- (void)setupGL;
+- (void)tearDownGL;
+
+- (BOOL)loadShaders;
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file;
+- (BOOL)linkProgram:(GLuint)prog;
+- (BOOL)validateProgram:(GLuint)prog;
+@end
+
+@implementation GameViewController
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+
+ if (!self.context) {
+ NSLog(@"Failed to create ES context");
+ }
+
+ GLKView *view = (GLKView *)self.view;
+ view.context = self.context;
+ view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
+
+ [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
+
+ [self setupGL];
+
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ];
+ self.imgui = [[ImGuiHelper alloc] initWithView:self.view ];
+ if (self.serverName)
+ {
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+ [self.imgui connectServer: self.serverName ];
+ }
+
+ DebugHUD_InitDefaults( &_hud );
+}
+
+- (void)dealloc
+{
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+
+ if ([self isViewLoaded] && ([[self view] window] == nil)) {
+ self.view = nil;
+
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+ self.context = nil;
+ }
+
+ // Dispose of any resources that can be recreated.
+}
+
+
+- (BOOL)prefersStatusBarHidden {
+ return YES;
+}
+
+- (IBAction)onServernameTapped:(id)sender
+{
+ UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ];
+ alert.alertViewStyle = UIAlertViewStylePlainTextInput;
+ alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to
+ [alert show];
+}
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG))
+ {
+ // This is really janky. I usually just hardcode the servername since I'm building it anyway.
+ // If you want to properly handle updating the server, you'll want to tear down and recreate
+ // the usynergy stuff in connectServer
+ BOOL serverNameWasSet = self.serverName.length > 0;
+ NSString *serverName = [[alertView textFieldAtIndex:0] text];
+
+ if ([serverName length] > 0) {
+ self.serverName = serverName;
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ [userDefaults setObject:serverName forKey:SERVERNAME_KEY ];
+ [userDefaults synchronize];
+
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+
+ // If we hadn't previously connected, try now
+ if (!serverNameWasSet) {
+ [self.imgui connectServer:self.serverName];
+ }
+ else
+ {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated"
+ message:@"Restart the app to connect the server"
+ delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
+ [alert show];
+ }
+ }
+ }
+}
+
+- (void)setupGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ [self loadShaders];
+
+ self.effect = [[GLKBaseEffect alloc] init];
+ self.effect.light0.enabled = GL_TRUE;
+ self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f);
+
+ glEnable(GL_DEPTH_TEST);
+
+ glGenVertexArraysOES(1, &_vertexArray);
+ glBindVertexArrayOES(_vertexArray);
+
+ glGenBuffers(1, &_vertexBuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);
+
+ glEnableVertexAttribArray(GLKVertexAttribPosition);
+ glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
+ glEnableVertexAttribArray(GLKVertexAttribNormal);
+ glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
+
+ glBindVertexArrayOES(0);
+
+
+}
+
+- (void)tearDownGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ glDeleteBuffers(1, &_vertexBuffer);
+ glDeleteVertexArraysOES(1, &_vertexArray);
+
+ self.effect = nil;
+
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+}
+
+#pragma mark - GLKView and GLKViewController delegate methods
+
+- (void)update
+{
+ float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height);
+ GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
+
+ self.effect.transform.projectionMatrix = projectionMatrix;
+
+ GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);
+ baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
+
+ // Compute the model view matrix for the object rendered with GLKit
+ GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ self.effect.transform.modelviewMatrix = modelViewMatrix;
+
+ // Compute the model view matrix for the object rendered with ES2
+ modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
+
+ _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
+
+ _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0));
+}
+
+
+- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
+{
+ glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glBindVertexArrayOES(_vertexArray);
+
+ // Render the object with GLKit
+ [self.effect prepareToDraw];
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ // Render the object again with ES2
+ glUseProgram(_program);
+
+ glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
+ glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
+ glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] );
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ [self.imgui newFrame];
+
+ // Now do our ImGUI UI
+ DebugHUD_DoInterface( &_hud );
+
+ self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f);
+
+ // Now render Imgui
+ [self.imgui render];
+
+}
+
+#pragma mark - OpenGL ES 2 shader compilation
+
+- (BOOL)loadShaders
+{
+ GLuint vertShader, fragShader;
+ NSString *vertShaderPathname, *fragShaderPathname;
+
+ // Create shader program.
+ _program = glCreateProgram();
+
+ // Create and compile vertex shader.
+ vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
+ if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
+ NSLog(@"Failed to compile vertex shader");
+ return NO;
+ }
+
+ // Create and compile fragment shader.
+ fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
+ if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
+ NSLog(@"Failed to compile fragment shader");
+ return NO;
+ }
+
+ // Attach vertex shader to program.
+ glAttachShader(_program, vertShader);
+
+ // Attach fragment shader to program.
+ glAttachShader(_program, fragShader);
+
+ // Bind attribute locations.
+ // This needs to be done prior to linking.
+ glBindAttribLocation(_program, GLKVertexAttribPosition, "position");
+ glBindAttribLocation(_program, GLKVertexAttribNormal, "normal");
+
+ // Link program.
+ if (![self linkProgram:_program]) {
+ NSLog(@"Failed to link program: %d", _program);
+
+ if (vertShader) {
+ glDeleteShader(vertShader);
+ vertShader = 0;
+ }
+ if (fragShader) {
+ glDeleteShader(fragShader);
+ fragShader = 0;
+ }
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+
+ return NO;
+ }
+
+ // Get uniform locations.
+ uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix");
+ uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix");
+ uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor");
+
+ // Release vertex and fragment shaders.
+ if (vertShader) {
+ glDetachShader(_program, vertShader);
+ glDeleteShader(vertShader);
+ }
+ if (fragShader) {
+ glDetachShader(_program, fragShader);
+ glDeleteShader(fragShader);
+ }
+
+ return YES;
+}
+
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
+{
+ GLint status;
+ const GLchar *source;
+
+ source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
+ if (!source) {
+ NSLog(@"Failed to load vertex shader");
+ return NO;
+ }
+
+ *shader = glCreateShader(type);
+ glShaderSource(*shader, 1, &source, NULL);
+ glCompileShader(*shader);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(*shader, logLength, &logLength, log);
+ NSLog(@"Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
+ if (status == 0) {
+ glDeleteShader(*shader);
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)linkProgram:(GLuint)prog
+{
+ GLint status;
+ glLinkProgram(prog);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program link log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetProgramiv(prog, GL_LINK_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)validateProgram:(GLuint)prog
+{
+ GLint logLength, status;
+
+ glValidateProgram(prog);
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program validate log:\n%s", log);
+ free(log);
+ }
+
+ glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..06b60d8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,77 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@2x~iphone.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@3x~iphone.png",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76~ipad.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76@2x~ipad.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "83.5x83.5",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
new file mode 100644
index 0000000..d728bc3
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
Binary files differ
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore
new file mode 100644
index 0000000..8feda89
--- /dev/null
+++ b/examples/apple_example/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+imguiex.xcodeproj/project.xcworkspace/
+imguiex.xcodeproj/xcuserdata/
\ No newline at end of file
diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md
new file mode 100644
index 0000000..339f6bf
--- /dev/null
+++ b/examples/apple_example/README.md
@@ -0,0 +1,41 @@
+# iOS / OSX example
+
+## Introduction
+
+This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device.
+
+It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy.
+
+Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active.
+
+## How to Use on iOS
+
+* In Synergy, go to Preferences, and uncheck "Use SSL encryption"
+* Run the example app.
+* Tap the "servername" button in the corner
+* Enter the name or the IP of your synergy host
+* If you had previously connected to a server, you may need to kill and re-start the app.
+
+## How to Build on OSX
+
+* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh)
+* Run the command: `brew install glfw3`
+* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme
+* Click `Run` button
+
+## Notes and TODOs
+
+Things that would be nice but I didn't get around to doing:
+
+* iOS software keyboard not supported for text inputs
+* iOS hardware (bluetooth) keyboards not supported
+* Graceful disconnect/reconnect from uSynergy.
+* Copy/Paste not well-supported
+
+## C++ on iOS / OSX
+
+ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension.
+
+Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer.
+
+In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly.
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h
new file mode 100644
index 0000000..82f1542
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.h
@@ -0,0 +1,13 @@
+//
+// AppDelegate.h
+// imguiex
+
+#import
+
+@interface AppDelegate : UIResponder
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m
new file mode 100644
index 0000000..ab83101
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.m
@@ -0,0 +1,41 @@
+//
+// AppDelegate.m
+// imguiex
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Override point for customization after application launch.
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
new file mode 100644
index 0000000..5717c00
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..90dfb2e
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h
new file mode 100644
index 0000000..3323cfd
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.h
@@ -0,0 +1,12 @@
+//
+// GameViewController.h
+// imguiex
+
+// This is the OpenGL Example template from XCode, modified to support ImGui
+
+#import
+#import
+
+@interface GameViewController : GLKViewController
+
+@end
diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m
new file mode 100644
index 0000000..e902f7a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.m
@@ -0,0 +1,481 @@
+//
+// GameViewController.m
+// imguiex
+//
+#import "GameViewController.h"
+#import
+
+#import "imgui_impl_ios.h"
+#import "debug_hud.h"
+
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
+
+#define SERVERNAME_KEY @"ServerName"
+
+#define SERVERNAME_ALERT_TAG (10)
+
+// Uniform index.
+enum
+{
+ UNIFORM_MODELVIEWPROJECTION_MATRIX,
+ UNIFORM_NORMAL_MATRIX,
+ UNIFORM_DIFFUSE_COLOR,
+
+ NUM_UNIFORMS
+};
+GLint uniforms[NUM_UNIFORMS];
+
+// Attribute index.
+enum
+{
+ ATTRIB_VERTEX,
+ ATTRIB_NORMAL,
+ NUM_ATTRIBUTES
+};
+
+GLfloat gCubeVertexData[216] =
+{
+ // Data layout for each line below is:
+ // positionX, positionY, positionZ, normalX, normalY, normalZ,
+ 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+
+ 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+
+ -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+
+ -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+
+ 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+
+ 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f
+};
+
+@interface GameViewController ()
+{
+ GLuint _program;
+
+ GLKMatrix4 _modelViewProjectionMatrix;
+ GLKMatrix3 _normalMatrix;
+ float _rotation;
+
+ GLuint _vertexArray;
+ GLuint _vertexBuffer;
+
+ DebugHUD _hud;
+}
+@property (strong, nonatomic) EAGLContext *context;
+@property (strong, nonatomic) GLKBaseEffect *effect;
+@property (strong, nonatomic) ImGuiHelper *imgui;
+@property (weak, nonatomic) IBOutlet UIButton *btnServername;
+
+@property (strong, nonatomic) NSString *serverName;
+
+- (IBAction)onServernameTapped:(id)sender;
+
+- (void)setupGL;
+- (void)tearDownGL;
+
+- (BOOL)loadShaders;
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file;
+- (BOOL)linkProgram:(GLuint)prog;
+- (BOOL)validateProgram:(GLuint)prog;
+@end
+
+@implementation GameViewController
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+
+ if (!self.context) {
+ NSLog(@"Failed to create ES context");
+ }
+
+ GLKView *view = (GLKView *)self.view;
+ view.context = self.context;
+ view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
+
+ [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
+
+ [self setupGL];
+
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ];
+ self.imgui = [[ImGuiHelper alloc] initWithView:self.view ];
+ if (self.serverName)
+ {
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+ [self.imgui connectServer: self.serverName ];
+ }
+
+ DebugHUD_InitDefaults( &_hud );
+}
+
+- (void)dealloc
+{
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+
+ if ([self isViewLoaded] && ([[self view] window] == nil)) {
+ self.view = nil;
+
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+ self.context = nil;
+ }
+
+ // Dispose of any resources that can be recreated.
+}
+
+
+- (BOOL)prefersStatusBarHidden {
+ return YES;
+}
+
+- (IBAction)onServernameTapped:(id)sender
+{
+ UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ];
+ alert.alertViewStyle = UIAlertViewStylePlainTextInput;
+ alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to
+ [alert show];
+}
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG))
+ {
+ // This is really janky. I usually just hardcode the servername since I'm building it anyway.
+ // If you want to properly handle updating the server, you'll want to tear down and recreate
+ // the usynergy stuff in connectServer
+ BOOL serverNameWasSet = self.serverName.length > 0;
+ NSString *serverName = [[alertView textFieldAtIndex:0] text];
+
+ if ([serverName length] > 0) {
+ self.serverName = serverName;
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ [userDefaults setObject:serverName forKey:SERVERNAME_KEY ];
+ [userDefaults synchronize];
+
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+
+ // If we hadn't previously connected, try now
+ if (!serverNameWasSet) {
+ [self.imgui connectServer:self.serverName];
+ }
+ else
+ {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated"
+ message:@"Restart the app to connect the server"
+ delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
+ [alert show];
+ }
+ }
+ }
+}
+
+- (void)setupGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ [self loadShaders];
+
+ self.effect = [[GLKBaseEffect alloc] init];
+ self.effect.light0.enabled = GL_TRUE;
+ self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f);
+
+ glEnable(GL_DEPTH_TEST);
+
+ glGenVertexArraysOES(1, &_vertexArray);
+ glBindVertexArrayOES(_vertexArray);
+
+ glGenBuffers(1, &_vertexBuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);
+
+ glEnableVertexAttribArray(GLKVertexAttribPosition);
+ glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
+ glEnableVertexAttribArray(GLKVertexAttribNormal);
+ glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
+
+ glBindVertexArrayOES(0);
+
+
+}
+
+- (void)tearDownGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ glDeleteBuffers(1, &_vertexBuffer);
+ glDeleteVertexArraysOES(1, &_vertexArray);
+
+ self.effect = nil;
+
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+}
+
+#pragma mark - GLKView and GLKViewController delegate methods
+
+- (void)update
+{
+ float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height);
+ GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
+
+ self.effect.transform.projectionMatrix = projectionMatrix;
+
+ GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);
+ baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
+
+ // Compute the model view matrix for the object rendered with GLKit
+ GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ self.effect.transform.modelviewMatrix = modelViewMatrix;
+
+ // Compute the model view matrix for the object rendered with ES2
+ modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
+
+ _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
+
+ _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0));
+}
+
+
+- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
+{
+ glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glBindVertexArrayOES(_vertexArray);
+
+ // Render the object with GLKit
+ [self.effect prepareToDraw];
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ // Render the object again with ES2
+ glUseProgram(_program);
+
+ glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
+ glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
+ glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] );
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ [self.imgui newFrame];
+
+ // Now do our ImGUI UI
+ DebugHUD_DoInterface( &_hud );
+
+ self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f);
+
+ // Now render Imgui
+ [self.imgui render];
+
+}
+
+#pragma mark - OpenGL ES 2 shader compilation
+
+- (BOOL)loadShaders
+{
+ GLuint vertShader, fragShader;
+ NSString *vertShaderPathname, *fragShaderPathname;
+
+ // Create shader program.
+ _program = glCreateProgram();
+
+ // Create and compile vertex shader.
+ vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
+ if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
+ NSLog(@"Failed to compile vertex shader");
+ return NO;
+ }
+
+ // Create and compile fragment shader.
+ fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
+ if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
+ NSLog(@"Failed to compile fragment shader");
+ return NO;
+ }
+
+ // Attach vertex shader to program.
+ glAttachShader(_program, vertShader);
+
+ // Attach fragment shader to program.
+ glAttachShader(_program, fragShader);
+
+ // Bind attribute locations.
+ // This needs to be done prior to linking.
+ glBindAttribLocation(_program, GLKVertexAttribPosition, "position");
+ glBindAttribLocation(_program, GLKVertexAttribNormal, "normal");
+
+ // Link program.
+ if (![self linkProgram:_program]) {
+ NSLog(@"Failed to link program: %d", _program);
+
+ if (vertShader) {
+ glDeleteShader(vertShader);
+ vertShader = 0;
+ }
+ if (fragShader) {
+ glDeleteShader(fragShader);
+ fragShader = 0;
+ }
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+
+ return NO;
+ }
+
+ // Get uniform locations.
+ uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix");
+ uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix");
+ uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor");
+
+ // Release vertex and fragment shaders.
+ if (vertShader) {
+ glDetachShader(_program, vertShader);
+ glDeleteShader(vertShader);
+ }
+ if (fragShader) {
+ glDetachShader(_program, fragShader);
+ glDeleteShader(fragShader);
+ }
+
+ return YES;
+}
+
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
+{
+ GLint status;
+ const GLchar *source;
+
+ source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
+ if (!source) {
+ NSLog(@"Failed to load vertex shader");
+ return NO;
+ }
+
+ *shader = glCreateShader(type);
+ glShaderSource(*shader, 1, &source, NULL);
+ glCompileShader(*shader);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(*shader, logLength, &logLength, log);
+ NSLog(@"Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
+ if (status == 0) {
+ glDeleteShader(*shader);
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)linkProgram:(GLuint)prog
+{
+ GLint status;
+ glLinkProgram(prog);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program link log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetProgramiv(prog, GL_LINK_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)validateProgram:(GLuint)prog
+{
+ GLint logLength, status;
+
+ glValidateProgram(prog);
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program validate log:\n%s", log);
+ free(log);
+ }
+
+ glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..06b60d8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,77 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@2x~iphone.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@3x~iphone.png",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76~ipad.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76@2x~ipad.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "83.5x83.5",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
new file mode 100644
index 0000000..d728bc3
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
new file mode 100644
index 0000000..f48b799
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
Binary files differ
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore
new file mode 100644
index 0000000..8feda89
--- /dev/null
+++ b/examples/apple_example/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+imguiex.xcodeproj/project.xcworkspace/
+imguiex.xcodeproj/xcuserdata/
\ No newline at end of file
diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md
new file mode 100644
index 0000000..339f6bf
--- /dev/null
+++ b/examples/apple_example/README.md
@@ -0,0 +1,41 @@
+# iOS / OSX example
+
+## Introduction
+
+This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device.
+
+It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy.
+
+Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active.
+
+## How to Use on iOS
+
+* In Synergy, go to Preferences, and uncheck "Use SSL encryption"
+* Run the example app.
+* Tap the "servername" button in the corner
+* Enter the name or the IP of your synergy host
+* If you had previously connected to a server, you may need to kill and re-start the app.
+
+## How to Build on OSX
+
+* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh)
+* Run the command: `brew install glfw3`
+* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme
+* Click `Run` button
+
+## Notes and TODOs
+
+Things that would be nice but I didn't get around to doing:
+
+* iOS software keyboard not supported for text inputs
+* iOS hardware (bluetooth) keyboards not supported
+* Graceful disconnect/reconnect from uSynergy.
+* Copy/Paste not well-supported
+
+## C++ on iOS / OSX
+
+ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension.
+
+Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer.
+
+In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly.
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h
new file mode 100644
index 0000000..82f1542
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.h
@@ -0,0 +1,13 @@
+//
+// AppDelegate.h
+// imguiex
+
+#import
+
+@interface AppDelegate : UIResponder
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m
new file mode 100644
index 0000000..ab83101
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.m
@@ -0,0 +1,41 @@
+//
+// AppDelegate.m
+// imguiex
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Override point for customization after application launch.
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
new file mode 100644
index 0000000..5717c00
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..90dfb2e
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h
new file mode 100644
index 0000000..3323cfd
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.h
@@ -0,0 +1,12 @@
+//
+// GameViewController.h
+// imguiex
+
+// This is the OpenGL Example template from XCode, modified to support ImGui
+
+#import
+#import
+
+@interface GameViewController : GLKViewController
+
+@end
diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m
new file mode 100644
index 0000000..e902f7a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.m
@@ -0,0 +1,481 @@
+//
+// GameViewController.m
+// imguiex
+//
+#import "GameViewController.h"
+#import
+
+#import "imgui_impl_ios.h"
+#import "debug_hud.h"
+
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
+
+#define SERVERNAME_KEY @"ServerName"
+
+#define SERVERNAME_ALERT_TAG (10)
+
+// Uniform index.
+enum
+{
+ UNIFORM_MODELVIEWPROJECTION_MATRIX,
+ UNIFORM_NORMAL_MATRIX,
+ UNIFORM_DIFFUSE_COLOR,
+
+ NUM_UNIFORMS
+};
+GLint uniforms[NUM_UNIFORMS];
+
+// Attribute index.
+enum
+{
+ ATTRIB_VERTEX,
+ ATTRIB_NORMAL,
+ NUM_ATTRIBUTES
+};
+
+GLfloat gCubeVertexData[216] =
+{
+ // Data layout for each line below is:
+ // positionX, positionY, positionZ, normalX, normalY, normalZ,
+ 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+
+ 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+
+ -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+
+ -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+
+ 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+
+ 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f
+};
+
+@interface GameViewController ()
+{
+ GLuint _program;
+
+ GLKMatrix4 _modelViewProjectionMatrix;
+ GLKMatrix3 _normalMatrix;
+ float _rotation;
+
+ GLuint _vertexArray;
+ GLuint _vertexBuffer;
+
+ DebugHUD _hud;
+}
+@property (strong, nonatomic) EAGLContext *context;
+@property (strong, nonatomic) GLKBaseEffect *effect;
+@property (strong, nonatomic) ImGuiHelper *imgui;
+@property (weak, nonatomic) IBOutlet UIButton *btnServername;
+
+@property (strong, nonatomic) NSString *serverName;
+
+- (IBAction)onServernameTapped:(id)sender;
+
+- (void)setupGL;
+- (void)tearDownGL;
+
+- (BOOL)loadShaders;
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file;
+- (BOOL)linkProgram:(GLuint)prog;
+- (BOOL)validateProgram:(GLuint)prog;
+@end
+
+@implementation GameViewController
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+
+ if (!self.context) {
+ NSLog(@"Failed to create ES context");
+ }
+
+ GLKView *view = (GLKView *)self.view;
+ view.context = self.context;
+ view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
+
+ [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
+
+ [self setupGL];
+
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ];
+ self.imgui = [[ImGuiHelper alloc] initWithView:self.view ];
+ if (self.serverName)
+ {
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+ [self.imgui connectServer: self.serverName ];
+ }
+
+ DebugHUD_InitDefaults( &_hud );
+}
+
+- (void)dealloc
+{
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+
+ if ([self isViewLoaded] && ([[self view] window] == nil)) {
+ self.view = nil;
+
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+ self.context = nil;
+ }
+
+ // Dispose of any resources that can be recreated.
+}
+
+
+- (BOOL)prefersStatusBarHidden {
+ return YES;
+}
+
+- (IBAction)onServernameTapped:(id)sender
+{
+ UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ];
+ alert.alertViewStyle = UIAlertViewStylePlainTextInput;
+ alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to
+ [alert show];
+}
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG))
+ {
+ // This is really janky. I usually just hardcode the servername since I'm building it anyway.
+ // If you want to properly handle updating the server, you'll want to tear down and recreate
+ // the usynergy stuff in connectServer
+ BOOL serverNameWasSet = self.serverName.length > 0;
+ NSString *serverName = [[alertView textFieldAtIndex:0] text];
+
+ if ([serverName length] > 0) {
+ self.serverName = serverName;
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ [userDefaults setObject:serverName forKey:SERVERNAME_KEY ];
+ [userDefaults synchronize];
+
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+
+ // If we hadn't previously connected, try now
+ if (!serverNameWasSet) {
+ [self.imgui connectServer:self.serverName];
+ }
+ else
+ {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated"
+ message:@"Restart the app to connect the server"
+ delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
+ [alert show];
+ }
+ }
+ }
+}
+
+- (void)setupGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ [self loadShaders];
+
+ self.effect = [[GLKBaseEffect alloc] init];
+ self.effect.light0.enabled = GL_TRUE;
+ self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f);
+
+ glEnable(GL_DEPTH_TEST);
+
+ glGenVertexArraysOES(1, &_vertexArray);
+ glBindVertexArrayOES(_vertexArray);
+
+ glGenBuffers(1, &_vertexBuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);
+
+ glEnableVertexAttribArray(GLKVertexAttribPosition);
+ glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
+ glEnableVertexAttribArray(GLKVertexAttribNormal);
+ glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
+
+ glBindVertexArrayOES(0);
+
+
+}
+
+- (void)tearDownGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ glDeleteBuffers(1, &_vertexBuffer);
+ glDeleteVertexArraysOES(1, &_vertexArray);
+
+ self.effect = nil;
+
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+}
+
+#pragma mark - GLKView and GLKViewController delegate methods
+
+- (void)update
+{
+ float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height);
+ GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
+
+ self.effect.transform.projectionMatrix = projectionMatrix;
+
+ GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);
+ baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
+
+ // Compute the model view matrix for the object rendered with GLKit
+ GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ self.effect.transform.modelviewMatrix = modelViewMatrix;
+
+ // Compute the model view matrix for the object rendered with ES2
+ modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
+
+ _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
+
+ _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0));
+}
+
+
+- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
+{
+ glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glBindVertexArrayOES(_vertexArray);
+
+ // Render the object with GLKit
+ [self.effect prepareToDraw];
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ // Render the object again with ES2
+ glUseProgram(_program);
+
+ glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
+ glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
+ glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] );
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ [self.imgui newFrame];
+
+ // Now do our ImGUI UI
+ DebugHUD_DoInterface( &_hud );
+
+ self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f);
+
+ // Now render Imgui
+ [self.imgui render];
+
+}
+
+#pragma mark - OpenGL ES 2 shader compilation
+
+- (BOOL)loadShaders
+{
+ GLuint vertShader, fragShader;
+ NSString *vertShaderPathname, *fragShaderPathname;
+
+ // Create shader program.
+ _program = glCreateProgram();
+
+ // Create and compile vertex shader.
+ vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
+ if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
+ NSLog(@"Failed to compile vertex shader");
+ return NO;
+ }
+
+ // Create and compile fragment shader.
+ fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
+ if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
+ NSLog(@"Failed to compile fragment shader");
+ return NO;
+ }
+
+ // Attach vertex shader to program.
+ glAttachShader(_program, vertShader);
+
+ // Attach fragment shader to program.
+ glAttachShader(_program, fragShader);
+
+ // Bind attribute locations.
+ // This needs to be done prior to linking.
+ glBindAttribLocation(_program, GLKVertexAttribPosition, "position");
+ glBindAttribLocation(_program, GLKVertexAttribNormal, "normal");
+
+ // Link program.
+ if (![self linkProgram:_program]) {
+ NSLog(@"Failed to link program: %d", _program);
+
+ if (vertShader) {
+ glDeleteShader(vertShader);
+ vertShader = 0;
+ }
+ if (fragShader) {
+ glDeleteShader(fragShader);
+ fragShader = 0;
+ }
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+
+ return NO;
+ }
+
+ // Get uniform locations.
+ uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix");
+ uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix");
+ uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor");
+
+ // Release vertex and fragment shaders.
+ if (vertShader) {
+ glDetachShader(_program, vertShader);
+ glDeleteShader(vertShader);
+ }
+ if (fragShader) {
+ glDetachShader(_program, fragShader);
+ glDeleteShader(fragShader);
+ }
+
+ return YES;
+}
+
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
+{
+ GLint status;
+ const GLchar *source;
+
+ source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
+ if (!source) {
+ NSLog(@"Failed to load vertex shader");
+ return NO;
+ }
+
+ *shader = glCreateShader(type);
+ glShaderSource(*shader, 1, &source, NULL);
+ glCompileShader(*shader);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(*shader, logLength, &logLength, log);
+ NSLog(@"Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
+ if (status == 0) {
+ glDeleteShader(*shader);
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)linkProgram:(GLuint)prog
+{
+ GLint status;
+ glLinkProgram(prog);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program link log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetProgramiv(prog, GL_LINK_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)validateProgram:(GLuint)prog
+{
+ GLint logLength, status;
+
+ glValidateProgram(prog);
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program validate log:\n%s", log);
+ free(log);
+ }
+
+ glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..06b60d8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,77 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@2x~iphone.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@3x~iphone.png",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76~ipad.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76@2x~ipad.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "83.5x83.5",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
new file mode 100644
index 0000000..d728bc3
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
new file mode 100644
index 0000000..f48b799
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
new file mode 100644
index 0000000..67b08b8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
Binary files differ
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore
new file mode 100644
index 0000000..8feda89
--- /dev/null
+++ b/examples/apple_example/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+imguiex.xcodeproj/project.xcworkspace/
+imguiex.xcodeproj/xcuserdata/
\ No newline at end of file
diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md
new file mode 100644
index 0000000..339f6bf
--- /dev/null
+++ b/examples/apple_example/README.md
@@ -0,0 +1,41 @@
+# iOS / OSX example
+
+## Introduction
+
+This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device.
+
+It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy.
+
+Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active.
+
+## How to Use on iOS
+
+* In Synergy, go to Preferences, and uncheck "Use SSL encryption"
+* Run the example app.
+* Tap the "servername" button in the corner
+* Enter the name or the IP of your synergy host
+* If you had previously connected to a server, you may need to kill and re-start the app.
+
+## How to Build on OSX
+
+* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh)
+* Run the command: `brew install glfw3`
+* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme
+* Click `Run` button
+
+## Notes and TODOs
+
+Things that would be nice but I didn't get around to doing:
+
+* iOS software keyboard not supported for text inputs
+* iOS hardware (bluetooth) keyboards not supported
+* Graceful disconnect/reconnect from uSynergy.
+* Copy/Paste not well-supported
+
+## C++ on iOS / OSX
+
+ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension.
+
+Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer.
+
+In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly.
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h
new file mode 100644
index 0000000..82f1542
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.h
@@ -0,0 +1,13 @@
+//
+// AppDelegate.h
+// imguiex
+
+#import
+
+@interface AppDelegate : UIResponder
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m
new file mode 100644
index 0000000..ab83101
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.m
@@ -0,0 +1,41 @@
+//
+// AppDelegate.m
+// imguiex
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Override point for customization after application launch.
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
new file mode 100644
index 0000000..5717c00
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..90dfb2e
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h
new file mode 100644
index 0000000..3323cfd
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.h
@@ -0,0 +1,12 @@
+//
+// GameViewController.h
+// imguiex
+
+// This is the OpenGL Example template from XCode, modified to support ImGui
+
+#import
+#import
+
+@interface GameViewController : GLKViewController
+
+@end
diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m
new file mode 100644
index 0000000..e902f7a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.m
@@ -0,0 +1,481 @@
+//
+// GameViewController.m
+// imguiex
+//
+#import "GameViewController.h"
+#import
+
+#import "imgui_impl_ios.h"
+#import "debug_hud.h"
+
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
+
+#define SERVERNAME_KEY @"ServerName"
+
+#define SERVERNAME_ALERT_TAG (10)
+
+// Uniform index.
+enum
+{
+ UNIFORM_MODELVIEWPROJECTION_MATRIX,
+ UNIFORM_NORMAL_MATRIX,
+ UNIFORM_DIFFUSE_COLOR,
+
+ NUM_UNIFORMS
+};
+GLint uniforms[NUM_UNIFORMS];
+
+// Attribute index.
+enum
+{
+ ATTRIB_VERTEX,
+ ATTRIB_NORMAL,
+ NUM_ATTRIBUTES
+};
+
+GLfloat gCubeVertexData[216] =
+{
+ // Data layout for each line below is:
+ // positionX, positionY, positionZ, normalX, normalY, normalZ,
+ 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+
+ 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+
+ -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+
+ -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+
+ 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+
+ 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f
+};
+
+@interface GameViewController ()
+{
+ GLuint _program;
+
+ GLKMatrix4 _modelViewProjectionMatrix;
+ GLKMatrix3 _normalMatrix;
+ float _rotation;
+
+ GLuint _vertexArray;
+ GLuint _vertexBuffer;
+
+ DebugHUD _hud;
+}
+@property (strong, nonatomic) EAGLContext *context;
+@property (strong, nonatomic) GLKBaseEffect *effect;
+@property (strong, nonatomic) ImGuiHelper *imgui;
+@property (weak, nonatomic) IBOutlet UIButton *btnServername;
+
+@property (strong, nonatomic) NSString *serverName;
+
+- (IBAction)onServernameTapped:(id)sender;
+
+- (void)setupGL;
+- (void)tearDownGL;
+
+- (BOOL)loadShaders;
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file;
+- (BOOL)linkProgram:(GLuint)prog;
+- (BOOL)validateProgram:(GLuint)prog;
+@end
+
+@implementation GameViewController
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+
+ if (!self.context) {
+ NSLog(@"Failed to create ES context");
+ }
+
+ GLKView *view = (GLKView *)self.view;
+ view.context = self.context;
+ view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
+
+ [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
+
+ [self setupGL];
+
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ];
+ self.imgui = [[ImGuiHelper alloc] initWithView:self.view ];
+ if (self.serverName)
+ {
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+ [self.imgui connectServer: self.serverName ];
+ }
+
+ DebugHUD_InitDefaults( &_hud );
+}
+
+- (void)dealloc
+{
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+
+ if ([self isViewLoaded] && ([[self view] window] == nil)) {
+ self.view = nil;
+
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+ self.context = nil;
+ }
+
+ // Dispose of any resources that can be recreated.
+}
+
+
+- (BOOL)prefersStatusBarHidden {
+ return YES;
+}
+
+- (IBAction)onServernameTapped:(id)sender
+{
+ UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ];
+ alert.alertViewStyle = UIAlertViewStylePlainTextInput;
+ alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to
+ [alert show];
+}
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG))
+ {
+ // This is really janky. I usually just hardcode the servername since I'm building it anyway.
+ // If you want to properly handle updating the server, you'll want to tear down and recreate
+ // the usynergy stuff in connectServer
+ BOOL serverNameWasSet = self.serverName.length > 0;
+ NSString *serverName = [[alertView textFieldAtIndex:0] text];
+
+ if ([serverName length] > 0) {
+ self.serverName = serverName;
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ [userDefaults setObject:serverName forKey:SERVERNAME_KEY ];
+ [userDefaults synchronize];
+
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+
+ // If we hadn't previously connected, try now
+ if (!serverNameWasSet) {
+ [self.imgui connectServer:self.serverName];
+ }
+ else
+ {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated"
+ message:@"Restart the app to connect the server"
+ delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
+ [alert show];
+ }
+ }
+ }
+}
+
+- (void)setupGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ [self loadShaders];
+
+ self.effect = [[GLKBaseEffect alloc] init];
+ self.effect.light0.enabled = GL_TRUE;
+ self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f);
+
+ glEnable(GL_DEPTH_TEST);
+
+ glGenVertexArraysOES(1, &_vertexArray);
+ glBindVertexArrayOES(_vertexArray);
+
+ glGenBuffers(1, &_vertexBuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);
+
+ glEnableVertexAttribArray(GLKVertexAttribPosition);
+ glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
+ glEnableVertexAttribArray(GLKVertexAttribNormal);
+ glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
+
+ glBindVertexArrayOES(0);
+
+
+}
+
+- (void)tearDownGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ glDeleteBuffers(1, &_vertexBuffer);
+ glDeleteVertexArraysOES(1, &_vertexArray);
+
+ self.effect = nil;
+
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+}
+
+#pragma mark - GLKView and GLKViewController delegate methods
+
+- (void)update
+{
+ float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height);
+ GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
+
+ self.effect.transform.projectionMatrix = projectionMatrix;
+
+ GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);
+ baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
+
+ // Compute the model view matrix for the object rendered with GLKit
+ GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ self.effect.transform.modelviewMatrix = modelViewMatrix;
+
+ // Compute the model view matrix for the object rendered with ES2
+ modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
+
+ _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
+
+ _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0));
+}
+
+
+- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
+{
+ glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glBindVertexArrayOES(_vertexArray);
+
+ // Render the object with GLKit
+ [self.effect prepareToDraw];
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ // Render the object again with ES2
+ glUseProgram(_program);
+
+ glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
+ glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
+ glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] );
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ [self.imgui newFrame];
+
+ // Now do our ImGUI UI
+ DebugHUD_DoInterface( &_hud );
+
+ self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f);
+
+ // Now render Imgui
+ [self.imgui render];
+
+}
+
+#pragma mark - OpenGL ES 2 shader compilation
+
+- (BOOL)loadShaders
+{
+ GLuint vertShader, fragShader;
+ NSString *vertShaderPathname, *fragShaderPathname;
+
+ // Create shader program.
+ _program = glCreateProgram();
+
+ // Create and compile vertex shader.
+ vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
+ if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
+ NSLog(@"Failed to compile vertex shader");
+ return NO;
+ }
+
+ // Create and compile fragment shader.
+ fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
+ if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
+ NSLog(@"Failed to compile fragment shader");
+ return NO;
+ }
+
+ // Attach vertex shader to program.
+ glAttachShader(_program, vertShader);
+
+ // Attach fragment shader to program.
+ glAttachShader(_program, fragShader);
+
+ // Bind attribute locations.
+ // This needs to be done prior to linking.
+ glBindAttribLocation(_program, GLKVertexAttribPosition, "position");
+ glBindAttribLocation(_program, GLKVertexAttribNormal, "normal");
+
+ // Link program.
+ if (![self linkProgram:_program]) {
+ NSLog(@"Failed to link program: %d", _program);
+
+ if (vertShader) {
+ glDeleteShader(vertShader);
+ vertShader = 0;
+ }
+ if (fragShader) {
+ glDeleteShader(fragShader);
+ fragShader = 0;
+ }
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+
+ return NO;
+ }
+
+ // Get uniform locations.
+ uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix");
+ uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix");
+ uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor");
+
+ // Release vertex and fragment shaders.
+ if (vertShader) {
+ glDetachShader(_program, vertShader);
+ glDeleteShader(vertShader);
+ }
+ if (fragShader) {
+ glDetachShader(_program, fragShader);
+ glDeleteShader(fragShader);
+ }
+
+ return YES;
+}
+
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
+{
+ GLint status;
+ const GLchar *source;
+
+ source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
+ if (!source) {
+ NSLog(@"Failed to load vertex shader");
+ return NO;
+ }
+
+ *shader = glCreateShader(type);
+ glShaderSource(*shader, 1, &source, NULL);
+ glCompileShader(*shader);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(*shader, logLength, &logLength, log);
+ NSLog(@"Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
+ if (status == 0) {
+ glDeleteShader(*shader);
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)linkProgram:(GLuint)prog
+{
+ GLint status;
+ glLinkProgram(prog);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program link log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetProgramiv(prog, GL_LINK_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)validateProgram:(GLuint)prog
+{
+ GLint logLength, status;
+
+ glValidateProgram(prog);
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program validate log:\n%s", log);
+ free(log);
+ }
+
+ glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..06b60d8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,77 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@2x~iphone.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@3x~iphone.png",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76~ipad.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76@2x~ipad.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "83.5x83.5",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
new file mode 100644
index 0000000..d728bc3
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
new file mode 100644
index 0000000..f48b799
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
new file mode 100644
index 0000000..67b08b8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
new file mode 100644
index 0000000..ae88e04
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
Binary files differ
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore
new file mode 100644
index 0000000..8feda89
--- /dev/null
+++ b/examples/apple_example/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+imguiex.xcodeproj/project.xcworkspace/
+imguiex.xcodeproj/xcuserdata/
\ No newline at end of file
diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md
new file mode 100644
index 0000000..339f6bf
--- /dev/null
+++ b/examples/apple_example/README.md
@@ -0,0 +1,41 @@
+# iOS / OSX example
+
+## Introduction
+
+This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device.
+
+It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy.
+
+Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active.
+
+## How to Use on iOS
+
+* In Synergy, go to Preferences, and uncheck "Use SSL encryption"
+* Run the example app.
+* Tap the "servername" button in the corner
+* Enter the name or the IP of your synergy host
+* If you had previously connected to a server, you may need to kill and re-start the app.
+
+## How to Build on OSX
+
+* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh)
+* Run the command: `brew install glfw3`
+* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme
+* Click `Run` button
+
+## Notes and TODOs
+
+Things that would be nice but I didn't get around to doing:
+
+* iOS software keyboard not supported for text inputs
+* iOS hardware (bluetooth) keyboards not supported
+* Graceful disconnect/reconnect from uSynergy.
+* Copy/Paste not well-supported
+
+## C++ on iOS / OSX
+
+ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension.
+
+Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer.
+
+In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly.
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h
new file mode 100644
index 0000000..82f1542
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.h
@@ -0,0 +1,13 @@
+//
+// AppDelegate.h
+// imguiex
+
+#import
+
+@interface AppDelegate : UIResponder
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m
new file mode 100644
index 0000000..ab83101
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.m
@@ -0,0 +1,41 @@
+//
+// AppDelegate.m
+// imguiex
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Override point for customization after application launch.
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
new file mode 100644
index 0000000..5717c00
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..90dfb2e
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h
new file mode 100644
index 0000000..3323cfd
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.h
@@ -0,0 +1,12 @@
+//
+// GameViewController.h
+// imguiex
+
+// This is the OpenGL Example template from XCode, modified to support ImGui
+
+#import
+#import
+
+@interface GameViewController : GLKViewController
+
+@end
diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m
new file mode 100644
index 0000000..e902f7a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.m
@@ -0,0 +1,481 @@
+//
+// GameViewController.m
+// imguiex
+//
+#import "GameViewController.h"
+#import
+
+#import "imgui_impl_ios.h"
+#import "debug_hud.h"
+
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
+
+#define SERVERNAME_KEY @"ServerName"
+
+#define SERVERNAME_ALERT_TAG (10)
+
+// Uniform index.
+enum
+{
+ UNIFORM_MODELVIEWPROJECTION_MATRIX,
+ UNIFORM_NORMAL_MATRIX,
+ UNIFORM_DIFFUSE_COLOR,
+
+ NUM_UNIFORMS
+};
+GLint uniforms[NUM_UNIFORMS];
+
+// Attribute index.
+enum
+{
+ ATTRIB_VERTEX,
+ ATTRIB_NORMAL,
+ NUM_ATTRIBUTES
+};
+
+GLfloat gCubeVertexData[216] =
+{
+ // Data layout for each line below is:
+ // positionX, positionY, positionZ, normalX, normalY, normalZ,
+ 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+
+ 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+
+ -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+
+ -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+
+ 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+
+ 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f
+};
+
+@interface GameViewController ()
+{
+ GLuint _program;
+
+ GLKMatrix4 _modelViewProjectionMatrix;
+ GLKMatrix3 _normalMatrix;
+ float _rotation;
+
+ GLuint _vertexArray;
+ GLuint _vertexBuffer;
+
+ DebugHUD _hud;
+}
+@property (strong, nonatomic) EAGLContext *context;
+@property (strong, nonatomic) GLKBaseEffect *effect;
+@property (strong, nonatomic) ImGuiHelper *imgui;
+@property (weak, nonatomic) IBOutlet UIButton *btnServername;
+
+@property (strong, nonatomic) NSString *serverName;
+
+- (IBAction)onServernameTapped:(id)sender;
+
+- (void)setupGL;
+- (void)tearDownGL;
+
+- (BOOL)loadShaders;
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file;
+- (BOOL)linkProgram:(GLuint)prog;
+- (BOOL)validateProgram:(GLuint)prog;
+@end
+
+@implementation GameViewController
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+
+ if (!self.context) {
+ NSLog(@"Failed to create ES context");
+ }
+
+ GLKView *view = (GLKView *)self.view;
+ view.context = self.context;
+ view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
+
+ [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
+
+ [self setupGL];
+
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ];
+ self.imgui = [[ImGuiHelper alloc] initWithView:self.view ];
+ if (self.serverName)
+ {
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+ [self.imgui connectServer: self.serverName ];
+ }
+
+ DebugHUD_InitDefaults( &_hud );
+}
+
+- (void)dealloc
+{
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+
+ if ([self isViewLoaded] && ([[self view] window] == nil)) {
+ self.view = nil;
+
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+ self.context = nil;
+ }
+
+ // Dispose of any resources that can be recreated.
+}
+
+
+- (BOOL)prefersStatusBarHidden {
+ return YES;
+}
+
+- (IBAction)onServernameTapped:(id)sender
+{
+ UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ];
+ alert.alertViewStyle = UIAlertViewStylePlainTextInput;
+ alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to
+ [alert show];
+}
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG))
+ {
+ // This is really janky. I usually just hardcode the servername since I'm building it anyway.
+ // If you want to properly handle updating the server, you'll want to tear down and recreate
+ // the usynergy stuff in connectServer
+ BOOL serverNameWasSet = self.serverName.length > 0;
+ NSString *serverName = [[alertView textFieldAtIndex:0] text];
+
+ if ([serverName length] > 0) {
+ self.serverName = serverName;
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ [userDefaults setObject:serverName forKey:SERVERNAME_KEY ];
+ [userDefaults synchronize];
+
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+
+ // If we hadn't previously connected, try now
+ if (!serverNameWasSet) {
+ [self.imgui connectServer:self.serverName];
+ }
+ else
+ {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated"
+ message:@"Restart the app to connect the server"
+ delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
+ [alert show];
+ }
+ }
+ }
+}
+
+- (void)setupGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ [self loadShaders];
+
+ self.effect = [[GLKBaseEffect alloc] init];
+ self.effect.light0.enabled = GL_TRUE;
+ self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f);
+
+ glEnable(GL_DEPTH_TEST);
+
+ glGenVertexArraysOES(1, &_vertexArray);
+ glBindVertexArrayOES(_vertexArray);
+
+ glGenBuffers(1, &_vertexBuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);
+
+ glEnableVertexAttribArray(GLKVertexAttribPosition);
+ glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
+ glEnableVertexAttribArray(GLKVertexAttribNormal);
+ glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
+
+ glBindVertexArrayOES(0);
+
+
+}
+
+- (void)tearDownGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ glDeleteBuffers(1, &_vertexBuffer);
+ glDeleteVertexArraysOES(1, &_vertexArray);
+
+ self.effect = nil;
+
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+}
+
+#pragma mark - GLKView and GLKViewController delegate methods
+
+- (void)update
+{
+ float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height);
+ GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
+
+ self.effect.transform.projectionMatrix = projectionMatrix;
+
+ GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);
+ baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
+
+ // Compute the model view matrix for the object rendered with GLKit
+ GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ self.effect.transform.modelviewMatrix = modelViewMatrix;
+
+ // Compute the model view matrix for the object rendered with ES2
+ modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
+
+ _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
+
+ _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0));
+}
+
+
+- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
+{
+ glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glBindVertexArrayOES(_vertexArray);
+
+ // Render the object with GLKit
+ [self.effect prepareToDraw];
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ // Render the object again with ES2
+ glUseProgram(_program);
+
+ glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
+ glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
+ glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] );
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ [self.imgui newFrame];
+
+ // Now do our ImGUI UI
+ DebugHUD_DoInterface( &_hud );
+
+ self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f);
+
+ // Now render Imgui
+ [self.imgui render];
+
+}
+
+#pragma mark - OpenGL ES 2 shader compilation
+
+- (BOOL)loadShaders
+{
+ GLuint vertShader, fragShader;
+ NSString *vertShaderPathname, *fragShaderPathname;
+
+ // Create shader program.
+ _program = glCreateProgram();
+
+ // Create and compile vertex shader.
+ vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
+ if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
+ NSLog(@"Failed to compile vertex shader");
+ return NO;
+ }
+
+ // Create and compile fragment shader.
+ fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
+ if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
+ NSLog(@"Failed to compile fragment shader");
+ return NO;
+ }
+
+ // Attach vertex shader to program.
+ glAttachShader(_program, vertShader);
+
+ // Attach fragment shader to program.
+ glAttachShader(_program, fragShader);
+
+ // Bind attribute locations.
+ // This needs to be done prior to linking.
+ glBindAttribLocation(_program, GLKVertexAttribPosition, "position");
+ glBindAttribLocation(_program, GLKVertexAttribNormal, "normal");
+
+ // Link program.
+ if (![self linkProgram:_program]) {
+ NSLog(@"Failed to link program: %d", _program);
+
+ if (vertShader) {
+ glDeleteShader(vertShader);
+ vertShader = 0;
+ }
+ if (fragShader) {
+ glDeleteShader(fragShader);
+ fragShader = 0;
+ }
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+
+ return NO;
+ }
+
+ // Get uniform locations.
+ uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix");
+ uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix");
+ uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor");
+
+ // Release vertex and fragment shaders.
+ if (vertShader) {
+ glDetachShader(_program, vertShader);
+ glDeleteShader(vertShader);
+ }
+ if (fragShader) {
+ glDetachShader(_program, fragShader);
+ glDeleteShader(fragShader);
+ }
+
+ return YES;
+}
+
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
+{
+ GLint status;
+ const GLchar *source;
+
+ source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
+ if (!source) {
+ NSLog(@"Failed to load vertex shader");
+ return NO;
+ }
+
+ *shader = glCreateShader(type);
+ glShaderSource(*shader, 1, &source, NULL);
+ glCompileShader(*shader);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(*shader, logLength, &logLength, log);
+ NSLog(@"Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
+ if (status == 0) {
+ glDeleteShader(*shader);
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)linkProgram:(GLuint)prog
+{
+ GLint status;
+ glLinkProgram(prog);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program link log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetProgramiv(prog, GL_LINK_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)validateProgram:(GLuint)prog
+{
+ GLint logLength, status;
+
+ glValidateProgram(prog);
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program validate log:\n%s", log);
+ free(log);
+ }
+
+ glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..06b60d8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,77 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@2x~iphone.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@3x~iphone.png",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76~ipad.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76@2x~ipad.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "83.5x83.5",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
new file mode 100644
index 0000000..d728bc3
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
new file mode 100644
index 0000000..f48b799
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
new file mode 100644
index 0000000..67b08b8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
new file mode 100644
index 0000000..ae88e04
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist
new file mode 100644
index 0000000..bc6f548
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Info.plist
@@ -0,0 +1,49 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ org.imgui.example.$(PRODUCT_NAME:rfc1034identifier)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UIStatusBarHidden
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore
new file mode 100644
index 0000000..8feda89
--- /dev/null
+++ b/examples/apple_example/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+imguiex.xcodeproj/project.xcworkspace/
+imguiex.xcodeproj/xcuserdata/
\ No newline at end of file
diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md
new file mode 100644
index 0000000..339f6bf
--- /dev/null
+++ b/examples/apple_example/README.md
@@ -0,0 +1,41 @@
+# iOS / OSX example
+
+## Introduction
+
+This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device.
+
+It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy.
+
+Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active.
+
+## How to Use on iOS
+
+* In Synergy, go to Preferences, and uncheck "Use SSL encryption"
+* Run the example app.
+* Tap the "servername" button in the corner
+* Enter the name or the IP of your synergy host
+* If you had previously connected to a server, you may need to kill and re-start the app.
+
+## How to Build on OSX
+
+* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh)
+* Run the command: `brew install glfw3`
+* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme
+* Click `Run` button
+
+## Notes and TODOs
+
+Things that would be nice but I didn't get around to doing:
+
+* iOS software keyboard not supported for text inputs
+* iOS hardware (bluetooth) keyboards not supported
+* Graceful disconnect/reconnect from uSynergy.
+* Copy/Paste not well-supported
+
+## C++ on iOS / OSX
+
+ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension.
+
+Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer.
+
+In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly.
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h
new file mode 100644
index 0000000..82f1542
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.h
@@ -0,0 +1,13 @@
+//
+// AppDelegate.h
+// imguiex
+
+#import
+
+@interface AppDelegate : UIResponder
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m
new file mode 100644
index 0000000..ab83101
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.m
@@ -0,0 +1,41 @@
+//
+// AppDelegate.m
+// imguiex
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Override point for customization after application launch.
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
new file mode 100644
index 0000000..5717c00
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..90dfb2e
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h
new file mode 100644
index 0000000..3323cfd
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.h
@@ -0,0 +1,12 @@
+//
+// GameViewController.h
+// imguiex
+
+// This is the OpenGL Example template from XCode, modified to support ImGui
+
+#import
+#import
+
+@interface GameViewController : GLKViewController
+
+@end
diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m
new file mode 100644
index 0000000..e902f7a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.m
@@ -0,0 +1,481 @@
+//
+// GameViewController.m
+// imguiex
+//
+#import "GameViewController.h"
+#import
+
+#import "imgui_impl_ios.h"
+#import "debug_hud.h"
+
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
+
+#define SERVERNAME_KEY @"ServerName"
+
+#define SERVERNAME_ALERT_TAG (10)
+
+// Uniform index.
+enum
+{
+ UNIFORM_MODELVIEWPROJECTION_MATRIX,
+ UNIFORM_NORMAL_MATRIX,
+ UNIFORM_DIFFUSE_COLOR,
+
+ NUM_UNIFORMS
+};
+GLint uniforms[NUM_UNIFORMS];
+
+// Attribute index.
+enum
+{
+ ATTRIB_VERTEX,
+ ATTRIB_NORMAL,
+ NUM_ATTRIBUTES
+};
+
+GLfloat gCubeVertexData[216] =
+{
+ // Data layout for each line below is:
+ // positionX, positionY, positionZ, normalX, normalY, normalZ,
+ 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+
+ 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+
+ -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+
+ -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+
+ 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+
+ 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f
+};
+
+@interface GameViewController ()
+{
+ GLuint _program;
+
+ GLKMatrix4 _modelViewProjectionMatrix;
+ GLKMatrix3 _normalMatrix;
+ float _rotation;
+
+ GLuint _vertexArray;
+ GLuint _vertexBuffer;
+
+ DebugHUD _hud;
+}
+@property (strong, nonatomic) EAGLContext *context;
+@property (strong, nonatomic) GLKBaseEffect *effect;
+@property (strong, nonatomic) ImGuiHelper *imgui;
+@property (weak, nonatomic) IBOutlet UIButton *btnServername;
+
+@property (strong, nonatomic) NSString *serverName;
+
+- (IBAction)onServernameTapped:(id)sender;
+
+- (void)setupGL;
+- (void)tearDownGL;
+
+- (BOOL)loadShaders;
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file;
+- (BOOL)linkProgram:(GLuint)prog;
+- (BOOL)validateProgram:(GLuint)prog;
+@end
+
+@implementation GameViewController
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+
+ if (!self.context) {
+ NSLog(@"Failed to create ES context");
+ }
+
+ GLKView *view = (GLKView *)self.view;
+ view.context = self.context;
+ view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
+
+ [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
+
+ [self setupGL];
+
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ];
+ self.imgui = [[ImGuiHelper alloc] initWithView:self.view ];
+ if (self.serverName)
+ {
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+ [self.imgui connectServer: self.serverName ];
+ }
+
+ DebugHUD_InitDefaults( &_hud );
+}
+
+- (void)dealloc
+{
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+
+ if ([self isViewLoaded] && ([[self view] window] == nil)) {
+ self.view = nil;
+
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+ self.context = nil;
+ }
+
+ // Dispose of any resources that can be recreated.
+}
+
+
+- (BOOL)prefersStatusBarHidden {
+ return YES;
+}
+
+- (IBAction)onServernameTapped:(id)sender
+{
+ UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ];
+ alert.alertViewStyle = UIAlertViewStylePlainTextInput;
+ alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to
+ [alert show];
+}
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG))
+ {
+ // This is really janky. I usually just hardcode the servername since I'm building it anyway.
+ // If you want to properly handle updating the server, you'll want to tear down and recreate
+ // the usynergy stuff in connectServer
+ BOOL serverNameWasSet = self.serverName.length > 0;
+ NSString *serverName = [[alertView textFieldAtIndex:0] text];
+
+ if ([serverName length] > 0) {
+ self.serverName = serverName;
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ [userDefaults setObject:serverName forKey:SERVERNAME_KEY ];
+ [userDefaults synchronize];
+
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+
+ // If we hadn't previously connected, try now
+ if (!serverNameWasSet) {
+ [self.imgui connectServer:self.serverName];
+ }
+ else
+ {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated"
+ message:@"Restart the app to connect the server"
+ delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
+ [alert show];
+ }
+ }
+ }
+}
+
+- (void)setupGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ [self loadShaders];
+
+ self.effect = [[GLKBaseEffect alloc] init];
+ self.effect.light0.enabled = GL_TRUE;
+ self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f);
+
+ glEnable(GL_DEPTH_TEST);
+
+ glGenVertexArraysOES(1, &_vertexArray);
+ glBindVertexArrayOES(_vertexArray);
+
+ glGenBuffers(1, &_vertexBuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);
+
+ glEnableVertexAttribArray(GLKVertexAttribPosition);
+ glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
+ glEnableVertexAttribArray(GLKVertexAttribNormal);
+ glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
+
+ glBindVertexArrayOES(0);
+
+
+}
+
+- (void)tearDownGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ glDeleteBuffers(1, &_vertexBuffer);
+ glDeleteVertexArraysOES(1, &_vertexArray);
+
+ self.effect = nil;
+
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+}
+
+#pragma mark - GLKView and GLKViewController delegate methods
+
+- (void)update
+{
+ float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height);
+ GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
+
+ self.effect.transform.projectionMatrix = projectionMatrix;
+
+ GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);
+ baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
+
+ // Compute the model view matrix for the object rendered with GLKit
+ GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ self.effect.transform.modelviewMatrix = modelViewMatrix;
+
+ // Compute the model view matrix for the object rendered with ES2
+ modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
+
+ _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
+
+ _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0));
+}
+
+
+- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
+{
+ glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glBindVertexArrayOES(_vertexArray);
+
+ // Render the object with GLKit
+ [self.effect prepareToDraw];
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ // Render the object again with ES2
+ glUseProgram(_program);
+
+ glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
+ glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
+ glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] );
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ [self.imgui newFrame];
+
+ // Now do our ImGUI UI
+ DebugHUD_DoInterface( &_hud );
+
+ self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f);
+
+ // Now render Imgui
+ [self.imgui render];
+
+}
+
+#pragma mark - OpenGL ES 2 shader compilation
+
+- (BOOL)loadShaders
+{
+ GLuint vertShader, fragShader;
+ NSString *vertShaderPathname, *fragShaderPathname;
+
+ // Create shader program.
+ _program = glCreateProgram();
+
+ // Create and compile vertex shader.
+ vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
+ if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
+ NSLog(@"Failed to compile vertex shader");
+ return NO;
+ }
+
+ // Create and compile fragment shader.
+ fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
+ if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
+ NSLog(@"Failed to compile fragment shader");
+ return NO;
+ }
+
+ // Attach vertex shader to program.
+ glAttachShader(_program, vertShader);
+
+ // Attach fragment shader to program.
+ glAttachShader(_program, fragShader);
+
+ // Bind attribute locations.
+ // This needs to be done prior to linking.
+ glBindAttribLocation(_program, GLKVertexAttribPosition, "position");
+ glBindAttribLocation(_program, GLKVertexAttribNormal, "normal");
+
+ // Link program.
+ if (![self linkProgram:_program]) {
+ NSLog(@"Failed to link program: %d", _program);
+
+ if (vertShader) {
+ glDeleteShader(vertShader);
+ vertShader = 0;
+ }
+ if (fragShader) {
+ glDeleteShader(fragShader);
+ fragShader = 0;
+ }
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+
+ return NO;
+ }
+
+ // Get uniform locations.
+ uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix");
+ uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix");
+ uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor");
+
+ // Release vertex and fragment shaders.
+ if (vertShader) {
+ glDetachShader(_program, vertShader);
+ glDeleteShader(vertShader);
+ }
+ if (fragShader) {
+ glDetachShader(_program, fragShader);
+ glDeleteShader(fragShader);
+ }
+
+ return YES;
+}
+
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
+{
+ GLint status;
+ const GLchar *source;
+
+ source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
+ if (!source) {
+ NSLog(@"Failed to load vertex shader");
+ return NO;
+ }
+
+ *shader = glCreateShader(type);
+ glShaderSource(*shader, 1, &source, NULL);
+ glCompileShader(*shader);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(*shader, logLength, &logLength, log);
+ NSLog(@"Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
+ if (status == 0) {
+ glDeleteShader(*shader);
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)linkProgram:(GLuint)prog
+{
+ GLint status;
+ glLinkProgram(prog);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program link log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetProgramiv(prog, GL_LINK_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)validateProgram:(GLuint)prog
+{
+ GLint logLength, status;
+
+ glValidateProgram(prog);
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program validate log:\n%s", log);
+ free(log);
+ }
+
+ glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..06b60d8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,77 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@2x~iphone.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@3x~iphone.png",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76~ipad.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76@2x~ipad.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "83.5x83.5",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
new file mode 100644
index 0000000..d728bc3
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
new file mode 100644
index 0000000..f48b799
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
new file mode 100644
index 0000000..67b08b8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
new file mode 100644
index 0000000..ae88e04
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist
new file mode 100644
index 0000000..bc6f548
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Info.plist
@@ -0,0 +1,49 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ org.imgui.example.$(PRODUCT_NAME:rfc1034identifier)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UIStatusBarHidden
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh
new file mode 100644
index 0000000..4000524
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh
@@ -0,0 +1,10 @@
+//
+// Shader.fsh
+// imguiex
+
+varying lowp vec4 colorVarying;
+
+void main()
+{
+ gl_FragColor = colorVarying;
+}
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore
new file mode 100644
index 0000000..8feda89
--- /dev/null
+++ b/examples/apple_example/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+imguiex.xcodeproj/project.xcworkspace/
+imguiex.xcodeproj/xcuserdata/
\ No newline at end of file
diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md
new file mode 100644
index 0000000..339f6bf
--- /dev/null
+++ b/examples/apple_example/README.md
@@ -0,0 +1,41 @@
+# iOS / OSX example
+
+## Introduction
+
+This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device.
+
+It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy.
+
+Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active.
+
+## How to Use on iOS
+
+* In Synergy, go to Preferences, and uncheck "Use SSL encryption"
+* Run the example app.
+* Tap the "servername" button in the corner
+* Enter the name or the IP of your synergy host
+* If you had previously connected to a server, you may need to kill and re-start the app.
+
+## How to Build on OSX
+
+* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh)
+* Run the command: `brew install glfw3`
+* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme
+* Click `Run` button
+
+## Notes and TODOs
+
+Things that would be nice but I didn't get around to doing:
+
+* iOS software keyboard not supported for text inputs
+* iOS hardware (bluetooth) keyboards not supported
+* Graceful disconnect/reconnect from uSynergy.
+* Copy/Paste not well-supported
+
+## C++ on iOS / OSX
+
+ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension.
+
+Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer.
+
+In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly.
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h
new file mode 100644
index 0000000..82f1542
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.h
@@ -0,0 +1,13 @@
+//
+// AppDelegate.h
+// imguiex
+
+#import
+
+@interface AppDelegate : UIResponder
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m
new file mode 100644
index 0000000..ab83101
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.m
@@ -0,0 +1,41 @@
+//
+// AppDelegate.m
+// imguiex
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Override point for customization after application launch.
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
new file mode 100644
index 0000000..5717c00
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..90dfb2e
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h
new file mode 100644
index 0000000..3323cfd
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.h
@@ -0,0 +1,12 @@
+//
+// GameViewController.h
+// imguiex
+
+// This is the OpenGL Example template from XCode, modified to support ImGui
+
+#import
+#import
+
+@interface GameViewController : GLKViewController
+
+@end
diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m
new file mode 100644
index 0000000..e902f7a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.m
@@ -0,0 +1,481 @@
+//
+// GameViewController.m
+// imguiex
+//
+#import "GameViewController.h"
+#import
+
+#import "imgui_impl_ios.h"
+#import "debug_hud.h"
+
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
+
+#define SERVERNAME_KEY @"ServerName"
+
+#define SERVERNAME_ALERT_TAG (10)
+
+// Uniform index.
+enum
+{
+ UNIFORM_MODELVIEWPROJECTION_MATRIX,
+ UNIFORM_NORMAL_MATRIX,
+ UNIFORM_DIFFUSE_COLOR,
+
+ NUM_UNIFORMS
+};
+GLint uniforms[NUM_UNIFORMS];
+
+// Attribute index.
+enum
+{
+ ATTRIB_VERTEX,
+ ATTRIB_NORMAL,
+ NUM_ATTRIBUTES
+};
+
+GLfloat gCubeVertexData[216] =
+{
+ // Data layout for each line below is:
+ // positionX, positionY, positionZ, normalX, normalY, normalZ,
+ 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+
+ 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+
+ -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+
+ -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+
+ 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+
+ 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f
+};
+
+@interface GameViewController ()
+{
+ GLuint _program;
+
+ GLKMatrix4 _modelViewProjectionMatrix;
+ GLKMatrix3 _normalMatrix;
+ float _rotation;
+
+ GLuint _vertexArray;
+ GLuint _vertexBuffer;
+
+ DebugHUD _hud;
+}
+@property (strong, nonatomic) EAGLContext *context;
+@property (strong, nonatomic) GLKBaseEffect *effect;
+@property (strong, nonatomic) ImGuiHelper *imgui;
+@property (weak, nonatomic) IBOutlet UIButton *btnServername;
+
+@property (strong, nonatomic) NSString *serverName;
+
+- (IBAction)onServernameTapped:(id)sender;
+
+- (void)setupGL;
+- (void)tearDownGL;
+
+- (BOOL)loadShaders;
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file;
+- (BOOL)linkProgram:(GLuint)prog;
+- (BOOL)validateProgram:(GLuint)prog;
+@end
+
+@implementation GameViewController
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+
+ if (!self.context) {
+ NSLog(@"Failed to create ES context");
+ }
+
+ GLKView *view = (GLKView *)self.view;
+ view.context = self.context;
+ view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
+
+ [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
+
+ [self setupGL];
+
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ];
+ self.imgui = [[ImGuiHelper alloc] initWithView:self.view ];
+ if (self.serverName)
+ {
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+ [self.imgui connectServer: self.serverName ];
+ }
+
+ DebugHUD_InitDefaults( &_hud );
+}
+
+- (void)dealloc
+{
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+
+ if ([self isViewLoaded] && ([[self view] window] == nil)) {
+ self.view = nil;
+
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+ self.context = nil;
+ }
+
+ // Dispose of any resources that can be recreated.
+}
+
+
+- (BOOL)prefersStatusBarHidden {
+ return YES;
+}
+
+- (IBAction)onServernameTapped:(id)sender
+{
+ UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ];
+ alert.alertViewStyle = UIAlertViewStylePlainTextInput;
+ alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to
+ [alert show];
+}
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG))
+ {
+ // This is really janky. I usually just hardcode the servername since I'm building it anyway.
+ // If you want to properly handle updating the server, you'll want to tear down and recreate
+ // the usynergy stuff in connectServer
+ BOOL serverNameWasSet = self.serverName.length > 0;
+ NSString *serverName = [[alertView textFieldAtIndex:0] text];
+
+ if ([serverName length] > 0) {
+ self.serverName = serverName;
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ [userDefaults setObject:serverName forKey:SERVERNAME_KEY ];
+ [userDefaults synchronize];
+
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+
+ // If we hadn't previously connected, try now
+ if (!serverNameWasSet) {
+ [self.imgui connectServer:self.serverName];
+ }
+ else
+ {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated"
+ message:@"Restart the app to connect the server"
+ delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
+ [alert show];
+ }
+ }
+ }
+}
+
+- (void)setupGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ [self loadShaders];
+
+ self.effect = [[GLKBaseEffect alloc] init];
+ self.effect.light0.enabled = GL_TRUE;
+ self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f);
+
+ glEnable(GL_DEPTH_TEST);
+
+ glGenVertexArraysOES(1, &_vertexArray);
+ glBindVertexArrayOES(_vertexArray);
+
+ glGenBuffers(1, &_vertexBuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);
+
+ glEnableVertexAttribArray(GLKVertexAttribPosition);
+ glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
+ glEnableVertexAttribArray(GLKVertexAttribNormal);
+ glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
+
+ glBindVertexArrayOES(0);
+
+
+}
+
+- (void)tearDownGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ glDeleteBuffers(1, &_vertexBuffer);
+ glDeleteVertexArraysOES(1, &_vertexArray);
+
+ self.effect = nil;
+
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+}
+
+#pragma mark - GLKView and GLKViewController delegate methods
+
+- (void)update
+{
+ float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height);
+ GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
+
+ self.effect.transform.projectionMatrix = projectionMatrix;
+
+ GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);
+ baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
+
+ // Compute the model view matrix for the object rendered with GLKit
+ GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ self.effect.transform.modelviewMatrix = modelViewMatrix;
+
+ // Compute the model view matrix for the object rendered with ES2
+ modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
+
+ _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
+
+ _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0));
+}
+
+
+- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
+{
+ glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glBindVertexArrayOES(_vertexArray);
+
+ // Render the object with GLKit
+ [self.effect prepareToDraw];
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ // Render the object again with ES2
+ glUseProgram(_program);
+
+ glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
+ glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
+ glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] );
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ [self.imgui newFrame];
+
+ // Now do our ImGUI UI
+ DebugHUD_DoInterface( &_hud );
+
+ self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f);
+
+ // Now render Imgui
+ [self.imgui render];
+
+}
+
+#pragma mark - OpenGL ES 2 shader compilation
+
+- (BOOL)loadShaders
+{
+ GLuint vertShader, fragShader;
+ NSString *vertShaderPathname, *fragShaderPathname;
+
+ // Create shader program.
+ _program = glCreateProgram();
+
+ // Create and compile vertex shader.
+ vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
+ if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
+ NSLog(@"Failed to compile vertex shader");
+ return NO;
+ }
+
+ // Create and compile fragment shader.
+ fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
+ if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
+ NSLog(@"Failed to compile fragment shader");
+ return NO;
+ }
+
+ // Attach vertex shader to program.
+ glAttachShader(_program, vertShader);
+
+ // Attach fragment shader to program.
+ glAttachShader(_program, fragShader);
+
+ // Bind attribute locations.
+ // This needs to be done prior to linking.
+ glBindAttribLocation(_program, GLKVertexAttribPosition, "position");
+ glBindAttribLocation(_program, GLKVertexAttribNormal, "normal");
+
+ // Link program.
+ if (![self linkProgram:_program]) {
+ NSLog(@"Failed to link program: %d", _program);
+
+ if (vertShader) {
+ glDeleteShader(vertShader);
+ vertShader = 0;
+ }
+ if (fragShader) {
+ glDeleteShader(fragShader);
+ fragShader = 0;
+ }
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+
+ return NO;
+ }
+
+ // Get uniform locations.
+ uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix");
+ uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix");
+ uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor");
+
+ // Release vertex and fragment shaders.
+ if (vertShader) {
+ glDetachShader(_program, vertShader);
+ glDeleteShader(vertShader);
+ }
+ if (fragShader) {
+ glDetachShader(_program, fragShader);
+ glDeleteShader(fragShader);
+ }
+
+ return YES;
+}
+
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
+{
+ GLint status;
+ const GLchar *source;
+
+ source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
+ if (!source) {
+ NSLog(@"Failed to load vertex shader");
+ return NO;
+ }
+
+ *shader = glCreateShader(type);
+ glShaderSource(*shader, 1, &source, NULL);
+ glCompileShader(*shader);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(*shader, logLength, &logLength, log);
+ NSLog(@"Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
+ if (status == 0) {
+ glDeleteShader(*shader);
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)linkProgram:(GLuint)prog
+{
+ GLint status;
+ glLinkProgram(prog);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program link log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetProgramiv(prog, GL_LINK_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)validateProgram:(GLuint)prog
+{
+ GLint logLength, status;
+
+ glValidateProgram(prog);
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program validate log:\n%s", log);
+ free(log);
+ }
+
+ glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..06b60d8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,77 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@2x~iphone.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@3x~iphone.png",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76~ipad.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76@2x~ipad.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "83.5x83.5",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
new file mode 100644
index 0000000..d728bc3
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
new file mode 100644
index 0000000..f48b799
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
new file mode 100644
index 0000000..67b08b8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
new file mode 100644
index 0000000..ae88e04
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist
new file mode 100644
index 0000000..bc6f548
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Info.plist
@@ -0,0 +1,49 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ org.imgui.example.$(PRODUCT_NAME:rfc1034identifier)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UIStatusBarHidden
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh
new file mode 100644
index 0000000..4000524
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh
@@ -0,0 +1,10 @@
+//
+// Shader.fsh
+// imguiex
+
+varying lowp vec4 colorVarying;
+
+void main()
+{
+ gl_FragColor = colorVarying;
+}
diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh
new file mode 100644
index 0000000..313c3d7
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh
@@ -0,0 +1,25 @@
+//
+// Shader.vsh
+// imguiex
+
+attribute vec4 position;
+attribute vec3 normal;
+
+varying lowp vec4 colorVarying;
+
+uniform vec3 diffuseColor;
+uniform mat4 modelViewProjectionMatrix;
+uniform mat3 normalMatrix;
+
+void main()
+{
+ vec3 eyeNormal = normalize(normalMatrix * normal);
+ vec3 lightPosition = vec3(0.0, 0.0, 1.0);
+
+ float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition)));
+
+ vec3 colorLit = diffuseColor * nDotVP;
+ colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 );
+
+ gl_Position = modelViewProjectionMatrix * position;
+}
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore
new file mode 100644
index 0000000..8feda89
--- /dev/null
+++ b/examples/apple_example/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+imguiex.xcodeproj/project.xcworkspace/
+imguiex.xcodeproj/xcuserdata/
\ No newline at end of file
diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md
new file mode 100644
index 0000000..339f6bf
--- /dev/null
+++ b/examples/apple_example/README.md
@@ -0,0 +1,41 @@
+# iOS / OSX example
+
+## Introduction
+
+This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device.
+
+It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy.
+
+Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active.
+
+## How to Use on iOS
+
+* In Synergy, go to Preferences, and uncheck "Use SSL encryption"
+* Run the example app.
+* Tap the "servername" button in the corner
+* Enter the name or the IP of your synergy host
+* If you had previously connected to a server, you may need to kill and re-start the app.
+
+## How to Build on OSX
+
+* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh)
+* Run the command: `brew install glfw3`
+* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme
+* Click `Run` button
+
+## Notes and TODOs
+
+Things that would be nice but I didn't get around to doing:
+
+* iOS software keyboard not supported for text inputs
+* iOS hardware (bluetooth) keyboards not supported
+* Graceful disconnect/reconnect from uSynergy.
+* Copy/Paste not well-supported
+
+## C++ on iOS / OSX
+
+ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension.
+
+Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer.
+
+In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly.
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h
new file mode 100644
index 0000000..82f1542
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.h
@@ -0,0 +1,13 @@
+//
+// AppDelegate.h
+// imguiex
+
+#import
+
+@interface AppDelegate : UIResponder
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m
new file mode 100644
index 0000000..ab83101
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.m
@@ -0,0 +1,41 @@
+//
+// AppDelegate.m
+// imguiex
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Override point for customization after application launch.
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
new file mode 100644
index 0000000..5717c00
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..90dfb2e
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h
new file mode 100644
index 0000000..3323cfd
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.h
@@ -0,0 +1,12 @@
+//
+// GameViewController.h
+// imguiex
+
+// This is the OpenGL Example template from XCode, modified to support ImGui
+
+#import
+#import
+
+@interface GameViewController : GLKViewController
+
+@end
diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m
new file mode 100644
index 0000000..e902f7a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.m
@@ -0,0 +1,481 @@
+//
+// GameViewController.m
+// imguiex
+//
+#import "GameViewController.h"
+#import
+
+#import "imgui_impl_ios.h"
+#import "debug_hud.h"
+
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
+
+#define SERVERNAME_KEY @"ServerName"
+
+#define SERVERNAME_ALERT_TAG (10)
+
+// Uniform index.
+enum
+{
+ UNIFORM_MODELVIEWPROJECTION_MATRIX,
+ UNIFORM_NORMAL_MATRIX,
+ UNIFORM_DIFFUSE_COLOR,
+
+ NUM_UNIFORMS
+};
+GLint uniforms[NUM_UNIFORMS];
+
+// Attribute index.
+enum
+{
+ ATTRIB_VERTEX,
+ ATTRIB_NORMAL,
+ NUM_ATTRIBUTES
+};
+
+GLfloat gCubeVertexData[216] =
+{
+ // Data layout for each line below is:
+ // positionX, positionY, positionZ, normalX, normalY, normalZ,
+ 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+
+ 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+
+ -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+
+ -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+
+ 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+
+ 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f
+};
+
+@interface GameViewController ()
+{
+ GLuint _program;
+
+ GLKMatrix4 _modelViewProjectionMatrix;
+ GLKMatrix3 _normalMatrix;
+ float _rotation;
+
+ GLuint _vertexArray;
+ GLuint _vertexBuffer;
+
+ DebugHUD _hud;
+}
+@property (strong, nonatomic) EAGLContext *context;
+@property (strong, nonatomic) GLKBaseEffect *effect;
+@property (strong, nonatomic) ImGuiHelper *imgui;
+@property (weak, nonatomic) IBOutlet UIButton *btnServername;
+
+@property (strong, nonatomic) NSString *serverName;
+
+- (IBAction)onServernameTapped:(id)sender;
+
+- (void)setupGL;
+- (void)tearDownGL;
+
+- (BOOL)loadShaders;
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file;
+- (BOOL)linkProgram:(GLuint)prog;
+- (BOOL)validateProgram:(GLuint)prog;
+@end
+
+@implementation GameViewController
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+
+ if (!self.context) {
+ NSLog(@"Failed to create ES context");
+ }
+
+ GLKView *view = (GLKView *)self.view;
+ view.context = self.context;
+ view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
+
+ [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
+
+ [self setupGL];
+
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ];
+ self.imgui = [[ImGuiHelper alloc] initWithView:self.view ];
+ if (self.serverName)
+ {
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+ [self.imgui connectServer: self.serverName ];
+ }
+
+ DebugHUD_InitDefaults( &_hud );
+}
+
+- (void)dealloc
+{
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+
+ if ([self isViewLoaded] && ([[self view] window] == nil)) {
+ self.view = nil;
+
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+ self.context = nil;
+ }
+
+ // Dispose of any resources that can be recreated.
+}
+
+
+- (BOOL)prefersStatusBarHidden {
+ return YES;
+}
+
+- (IBAction)onServernameTapped:(id)sender
+{
+ UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ];
+ alert.alertViewStyle = UIAlertViewStylePlainTextInput;
+ alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to
+ [alert show];
+}
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG))
+ {
+ // This is really janky. I usually just hardcode the servername since I'm building it anyway.
+ // If you want to properly handle updating the server, you'll want to tear down and recreate
+ // the usynergy stuff in connectServer
+ BOOL serverNameWasSet = self.serverName.length > 0;
+ NSString *serverName = [[alertView textFieldAtIndex:0] text];
+
+ if ([serverName length] > 0) {
+ self.serverName = serverName;
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ [userDefaults setObject:serverName forKey:SERVERNAME_KEY ];
+ [userDefaults synchronize];
+
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+
+ // If we hadn't previously connected, try now
+ if (!serverNameWasSet) {
+ [self.imgui connectServer:self.serverName];
+ }
+ else
+ {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated"
+ message:@"Restart the app to connect the server"
+ delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
+ [alert show];
+ }
+ }
+ }
+}
+
+- (void)setupGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ [self loadShaders];
+
+ self.effect = [[GLKBaseEffect alloc] init];
+ self.effect.light0.enabled = GL_TRUE;
+ self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f);
+
+ glEnable(GL_DEPTH_TEST);
+
+ glGenVertexArraysOES(1, &_vertexArray);
+ glBindVertexArrayOES(_vertexArray);
+
+ glGenBuffers(1, &_vertexBuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);
+
+ glEnableVertexAttribArray(GLKVertexAttribPosition);
+ glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
+ glEnableVertexAttribArray(GLKVertexAttribNormal);
+ glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
+
+ glBindVertexArrayOES(0);
+
+
+}
+
+- (void)tearDownGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ glDeleteBuffers(1, &_vertexBuffer);
+ glDeleteVertexArraysOES(1, &_vertexArray);
+
+ self.effect = nil;
+
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+}
+
+#pragma mark - GLKView and GLKViewController delegate methods
+
+- (void)update
+{
+ float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height);
+ GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
+
+ self.effect.transform.projectionMatrix = projectionMatrix;
+
+ GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);
+ baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
+
+ // Compute the model view matrix for the object rendered with GLKit
+ GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ self.effect.transform.modelviewMatrix = modelViewMatrix;
+
+ // Compute the model view matrix for the object rendered with ES2
+ modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
+
+ _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
+
+ _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0));
+}
+
+
+- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
+{
+ glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glBindVertexArrayOES(_vertexArray);
+
+ // Render the object with GLKit
+ [self.effect prepareToDraw];
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ // Render the object again with ES2
+ glUseProgram(_program);
+
+ glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
+ glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
+ glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] );
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ [self.imgui newFrame];
+
+ // Now do our ImGUI UI
+ DebugHUD_DoInterface( &_hud );
+
+ self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f);
+
+ // Now render Imgui
+ [self.imgui render];
+
+}
+
+#pragma mark - OpenGL ES 2 shader compilation
+
+- (BOOL)loadShaders
+{
+ GLuint vertShader, fragShader;
+ NSString *vertShaderPathname, *fragShaderPathname;
+
+ // Create shader program.
+ _program = glCreateProgram();
+
+ // Create and compile vertex shader.
+ vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
+ if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
+ NSLog(@"Failed to compile vertex shader");
+ return NO;
+ }
+
+ // Create and compile fragment shader.
+ fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
+ if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
+ NSLog(@"Failed to compile fragment shader");
+ return NO;
+ }
+
+ // Attach vertex shader to program.
+ glAttachShader(_program, vertShader);
+
+ // Attach fragment shader to program.
+ glAttachShader(_program, fragShader);
+
+ // Bind attribute locations.
+ // This needs to be done prior to linking.
+ glBindAttribLocation(_program, GLKVertexAttribPosition, "position");
+ glBindAttribLocation(_program, GLKVertexAttribNormal, "normal");
+
+ // Link program.
+ if (![self linkProgram:_program]) {
+ NSLog(@"Failed to link program: %d", _program);
+
+ if (vertShader) {
+ glDeleteShader(vertShader);
+ vertShader = 0;
+ }
+ if (fragShader) {
+ glDeleteShader(fragShader);
+ fragShader = 0;
+ }
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+
+ return NO;
+ }
+
+ // Get uniform locations.
+ uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix");
+ uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix");
+ uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor");
+
+ // Release vertex and fragment shaders.
+ if (vertShader) {
+ glDetachShader(_program, vertShader);
+ glDeleteShader(vertShader);
+ }
+ if (fragShader) {
+ glDetachShader(_program, fragShader);
+ glDeleteShader(fragShader);
+ }
+
+ return YES;
+}
+
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
+{
+ GLint status;
+ const GLchar *source;
+
+ source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
+ if (!source) {
+ NSLog(@"Failed to load vertex shader");
+ return NO;
+ }
+
+ *shader = glCreateShader(type);
+ glShaderSource(*shader, 1, &source, NULL);
+ glCompileShader(*shader);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(*shader, logLength, &logLength, log);
+ NSLog(@"Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
+ if (status == 0) {
+ glDeleteShader(*shader);
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)linkProgram:(GLuint)prog
+{
+ GLint status;
+ glLinkProgram(prog);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program link log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetProgramiv(prog, GL_LINK_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)validateProgram:(GLuint)prog
+{
+ GLint logLength, status;
+
+ glValidateProgram(prog);
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program validate log:\n%s", log);
+ free(log);
+ }
+
+ glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..06b60d8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,77 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@2x~iphone.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@3x~iphone.png",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76~ipad.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76@2x~ipad.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "83.5x83.5",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
new file mode 100644
index 0000000..d728bc3
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
new file mode 100644
index 0000000..f48b799
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
new file mode 100644
index 0000000..67b08b8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
new file mode 100644
index 0000000..ae88e04
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist
new file mode 100644
index 0000000..bc6f548
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Info.plist
@@ -0,0 +1,49 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ org.imgui.example.$(PRODUCT_NAME:rfc1034identifier)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UIStatusBarHidden
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh
new file mode 100644
index 0000000..4000524
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh
@@ -0,0 +1,10 @@
+//
+// Shader.fsh
+// imguiex
+
+varying lowp vec4 colorVarying;
+
+void main()
+{
+ gl_FragColor = colorVarying;
+}
diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh
new file mode 100644
index 0000000..313c3d7
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh
@@ -0,0 +1,25 @@
+//
+// Shader.vsh
+// imguiex
+
+attribute vec4 position;
+attribute vec3 normal;
+
+varying lowp vec4 colorVarying;
+
+uniform vec3 diffuseColor;
+uniform mat4 modelViewProjectionMatrix;
+uniform mat3 normalMatrix;
+
+void main()
+{
+ vec3 eyeNormal = normalize(normalMatrix * normal);
+ vec3 lightPosition = vec3(0.0, 0.0, 1.0);
+
+ float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition)));
+
+ vec3 colorLit = diffuseColor * nDotVP;
+ colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 );
+
+ gl_Position = modelViewProjectionMatrix * position;
+}
diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp
new file mode 100644
index 0000000..c75938a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/debug_hud.cpp
@@ -0,0 +1,45 @@
+//
+// debug_hud.cpp
+// imguiex
+
+#include
+
+#include "debug_hud.h"
+#include "imgui.h"
+
+void DebugHUD_InitDefaults( DebugHUD *hud )
+{
+ hud->show_test_window = true;
+ hud->show_example_window = true;
+ hud->rotation_speed = 15.0f;
+
+ hud->cubeColor1[0] = 0.4f;
+ hud->cubeColor1[1] = 0.4f;
+ hud->cubeColor1[2] = 1.0f;
+ hud->cubeColor1[3] = 1.0f;
+
+ hud->cubeColor2[0] = 1.0f;
+ hud->cubeColor2[1] = 0.4f;
+ hud->cubeColor2[2] = 0.4f;
+ hud->cubeColor2[3] = 1.0f;
+}
+
+void DebugHUD_DoInterface( DebugHUD *hud )
+{
+ if (hud->show_test_window)
+ {
+ ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver );
+ ImGui::ShowTestWindow( &hud->show_test_window );
+ }
+
+ if (hud->show_example_window)
+ {
+ ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver );
+ ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver );
+ ImGui::Begin("Another Window", &hud->show_example_window);
+ ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1);
+ ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2);
+ ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f);
+ ImGui::End();
+ }
+}
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore
new file mode 100644
index 0000000..8feda89
--- /dev/null
+++ b/examples/apple_example/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+imguiex.xcodeproj/project.xcworkspace/
+imguiex.xcodeproj/xcuserdata/
\ No newline at end of file
diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md
new file mode 100644
index 0000000..339f6bf
--- /dev/null
+++ b/examples/apple_example/README.md
@@ -0,0 +1,41 @@
+# iOS / OSX example
+
+## Introduction
+
+This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device.
+
+It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy.
+
+Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active.
+
+## How to Use on iOS
+
+* In Synergy, go to Preferences, and uncheck "Use SSL encryption"
+* Run the example app.
+* Tap the "servername" button in the corner
+* Enter the name or the IP of your synergy host
+* If you had previously connected to a server, you may need to kill and re-start the app.
+
+## How to Build on OSX
+
+* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh)
+* Run the command: `brew install glfw3`
+* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme
+* Click `Run` button
+
+## Notes and TODOs
+
+Things that would be nice but I didn't get around to doing:
+
+* iOS software keyboard not supported for text inputs
+* iOS hardware (bluetooth) keyboards not supported
+* Graceful disconnect/reconnect from uSynergy.
+* Copy/Paste not well-supported
+
+## C++ on iOS / OSX
+
+ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension.
+
+Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer.
+
+In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly.
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h
new file mode 100644
index 0000000..82f1542
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.h
@@ -0,0 +1,13 @@
+//
+// AppDelegate.h
+// imguiex
+
+#import
+
+@interface AppDelegate : UIResponder
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m
new file mode 100644
index 0000000..ab83101
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.m
@@ -0,0 +1,41 @@
+//
+// AppDelegate.m
+// imguiex
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Override point for customization after application launch.
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
new file mode 100644
index 0000000..5717c00
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..90dfb2e
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h
new file mode 100644
index 0000000..3323cfd
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.h
@@ -0,0 +1,12 @@
+//
+// GameViewController.h
+// imguiex
+
+// This is the OpenGL Example template from XCode, modified to support ImGui
+
+#import
+#import
+
+@interface GameViewController : GLKViewController
+
+@end
diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m
new file mode 100644
index 0000000..e902f7a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.m
@@ -0,0 +1,481 @@
+//
+// GameViewController.m
+// imguiex
+//
+#import "GameViewController.h"
+#import
+
+#import "imgui_impl_ios.h"
+#import "debug_hud.h"
+
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
+
+#define SERVERNAME_KEY @"ServerName"
+
+#define SERVERNAME_ALERT_TAG (10)
+
+// Uniform index.
+enum
+{
+ UNIFORM_MODELVIEWPROJECTION_MATRIX,
+ UNIFORM_NORMAL_MATRIX,
+ UNIFORM_DIFFUSE_COLOR,
+
+ NUM_UNIFORMS
+};
+GLint uniforms[NUM_UNIFORMS];
+
+// Attribute index.
+enum
+{
+ ATTRIB_VERTEX,
+ ATTRIB_NORMAL,
+ NUM_ATTRIBUTES
+};
+
+GLfloat gCubeVertexData[216] =
+{
+ // Data layout for each line below is:
+ // positionX, positionY, positionZ, normalX, normalY, normalZ,
+ 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+
+ 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+
+ -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+
+ -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+
+ 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+
+ 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f
+};
+
+@interface GameViewController ()
+{
+ GLuint _program;
+
+ GLKMatrix4 _modelViewProjectionMatrix;
+ GLKMatrix3 _normalMatrix;
+ float _rotation;
+
+ GLuint _vertexArray;
+ GLuint _vertexBuffer;
+
+ DebugHUD _hud;
+}
+@property (strong, nonatomic) EAGLContext *context;
+@property (strong, nonatomic) GLKBaseEffect *effect;
+@property (strong, nonatomic) ImGuiHelper *imgui;
+@property (weak, nonatomic) IBOutlet UIButton *btnServername;
+
+@property (strong, nonatomic) NSString *serverName;
+
+- (IBAction)onServernameTapped:(id)sender;
+
+- (void)setupGL;
+- (void)tearDownGL;
+
+- (BOOL)loadShaders;
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file;
+- (BOOL)linkProgram:(GLuint)prog;
+- (BOOL)validateProgram:(GLuint)prog;
+@end
+
+@implementation GameViewController
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+
+ if (!self.context) {
+ NSLog(@"Failed to create ES context");
+ }
+
+ GLKView *view = (GLKView *)self.view;
+ view.context = self.context;
+ view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
+
+ [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
+
+ [self setupGL];
+
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ];
+ self.imgui = [[ImGuiHelper alloc] initWithView:self.view ];
+ if (self.serverName)
+ {
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+ [self.imgui connectServer: self.serverName ];
+ }
+
+ DebugHUD_InitDefaults( &_hud );
+}
+
+- (void)dealloc
+{
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+
+ if ([self isViewLoaded] && ([[self view] window] == nil)) {
+ self.view = nil;
+
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+ self.context = nil;
+ }
+
+ // Dispose of any resources that can be recreated.
+}
+
+
+- (BOOL)prefersStatusBarHidden {
+ return YES;
+}
+
+- (IBAction)onServernameTapped:(id)sender
+{
+ UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ];
+ alert.alertViewStyle = UIAlertViewStylePlainTextInput;
+ alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to
+ [alert show];
+}
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG))
+ {
+ // This is really janky. I usually just hardcode the servername since I'm building it anyway.
+ // If you want to properly handle updating the server, you'll want to tear down and recreate
+ // the usynergy stuff in connectServer
+ BOOL serverNameWasSet = self.serverName.length > 0;
+ NSString *serverName = [[alertView textFieldAtIndex:0] text];
+
+ if ([serverName length] > 0) {
+ self.serverName = serverName;
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ [userDefaults setObject:serverName forKey:SERVERNAME_KEY ];
+ [userDefaults synchronize];
+
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+
+ // If we hadn't previously connected, try now
+ if (!serverNameWasSet) {
+ [self.imgui connectServer:self.serverName];
+ }
+ else
+ {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated"
+ message:@"Restart the app to connect the server"
+ delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
+ [alert show];
+ }
+ }
+ }
+}
+
+- (void)setupGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ [self loadShaders];
+
+ self.effect = [[GLKBaseEffect alloc] init];
+ self.effect.light0.enabled = GL_TRUE;
+ self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f);
+
+ glEnable(GL_DEPTH_TEST);
+
+ glGenVertexArraysOES(1, &_vertexArray);
+ glBindVertexArrayOES(_vertexArray);
+
+ glGenBuffers(1, &_vertexBuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);
+
+ glEnableVertexAttribArray(GLKVertexAttribPosition);
+ glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
+ glEnableVertexAttribArray(GLKVertexAttribNormal);
+ glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
+
+ glBindVertexArrayOES(0);
+
+
+}
+
+- (void)tearDownGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ glDeleteBuffers(1, &_vertexBuffer);
+ glDeleteVertexArraysOES(1, &_vertexArray);
+
+ self.effect = nil;
+
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+}
+
+#pragma mark - GLKView and GLKViewController delegate methods
+
+- (void)update
+{
+ float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height);
+ GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
+
+ self.effect.transform.projectionMatrix = projectionMatrix;
+
+ GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);
+ baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
+
+ // Compute the model view matrix for the object rendered with GLKit
+ GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ self.effect.transform.modelviewMatrix = modelViewMatrix;
+
+ // Compute the model view matrix for the object rendered with ES2
+ modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
+
+ _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
+
+ _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0));
+}
+
+
+- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
+{
+ glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glBindVertexArrayOES(_vertexArray);
+
+ // Render the object with GLKit
+ [self.effect prepareToDraw];
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ // Render the object again with ES2
+ glUseProgram(_program);
+
+ glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
+ glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
+ glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] );
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ [self.imgui newFrame];
+
+ // Now do our ImGUI UI
+ DebugHUD_DoInterface( &_hud );
+
+ self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f);
+
+ // Now render Imgui
+ [self.imgui render];
+
+}
+
+#pragma mark - OpenGL ES 2 shader compilation
+
+- (BOOL)loadShaders
+{
+ GLuint vertShader, fragShader;
+ NSString *vertShaderPathname, *fragShaderPathname;
+
+ // Create shader program.
+ _program = glCreateProgram();
+
+ // Create and compile vertex shader.
+ vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
+ if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
+ NSLog(@"Failed to compile vertex shader");
+ return NO;
+ }
+
+ // Create and compile fragment shader.
+ fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
+ if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
+ NSLog(@"Failed to compile fragment shader");
+ return NO;
+ }
+
+ // Attach vertex shader to program.
+ glAttachShader(_program, vertShader);
+
+ // Attach fragment shader to program.
+ glAttachShader(_program, fragShader);
+
+ // Bind attribute locations.
+ // This needs to be done prior to linking.
+ glBindAttribLocation(_program, GLKVertexAttribPosition, "position");
+ glBindAttribLocation(_program, GLKVertexAttribNormal, "normal");
+
+ // Link program.
+ if (![self linkProgram:_program]) {
+ NSLog(@"Failed to link program: %d", _program);
+
+ if (vertShader) {
+ glDeleteShader(vertShader);
+ vertShader = 0;
+ }
+ if (fragShader) {
+ glDeleteShader(fragShader);
+ fragShader = 0;
+ }
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+
+ return NO;
+ }
+
+ // Get uniform locations.
+ uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix");
+ uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix");
+ uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor");
+
+ // Release vertex and fragment shaders.
+ if (vertShader) {
+ glDetachShader(_program, vertShader);
+ glDeleteShader(vertShader);
+ }
+ if (fragShader) {
+ glDetachShader(_program, fragShader);
+ glDeleteShader(fragShader);
+ }
+
+ return YES;
+}
+
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
+{
+ GLint status;
+ const GLchar *source;
+
+ source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
+ if (!source) {
+ NSLog(@"Failed to load vertex shader");
+ return NO;
+ }
+
+ *shader = glCreateShader(type);
+ glShaderSource(*shader, 1, &source, NULL);
+ glCompileShader(*shader);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(*shader, logLength, &logLength, log);
+ NSLog(@"Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
+ if (status == 0) {
+ glDeleteShader(*shader);
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)linkProgram:(GLuint)prog
+{
+ GLint status;
+ glLinkProgram(prog);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program link log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetProgramiv(prog, GL_LINK_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)validateProgram:(GLuint)prog
+{
+ GLint logLength, status;
+
+ glValidateProgram(prog);
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program validate log:\n%s", log);
+ free(log);
+ }
+
+ glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..06b60d8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,77 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@2x~iphone.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@3x~iphone.png",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76~ipad.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76@2x~ipad.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "83.5x83.5",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
new file mode 100644
index 0000000..d728bc3
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
new file mode 100644
index 0000000..f48b799
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
new file mode 100644
index 0000000..67b08b8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
new file mode 100644
index 0000000..ae88e04
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist
new file mode 100644
index 0000000..bc6f548
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Info.plist
@@ -0,0 +1,49 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ org.imgui.example.$(PRODUCT_NAME:rfc1034identifier)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UIStatusBarHidden
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh
new file mode 100644
index 0000000..4000524
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh
@@ -0,0 +1,10 @@
+//
+// Shader.fsh
+// imguiex
+
+varying lowp vec4 colorVarying;
+
+void main()
+{
+ gl_FragColor = colorVarying;
+}
diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh
new file mode 100644
index 0000000..313c3d7
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh
@@ -0,0 +1,25 @@
+//
+// Shader.vsh
+// imguiex
+
+attribute vec4 position;
+attribute vec3 normal;
+
+varying lowp vec4 colorVarying;
+
+uniform vec3 diffuseColor;
+uniform mat4 modelViewProjectionMatrix;
+uniform mat3 normalMatrix;
+
+void main()
+{
+ vec3 eyeNormal = normalize(normalMatrix * normal);
+ vec3 lightPosition = vec3(0.0, 0.0, 1.0);
+
+ float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition)));
+
+ vec3 colorLit = diffuseColor * nDotVP;
+ colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 );
+
+ gl_Position = modelViewProjectionMatrix * position;
+}
diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp
new file mode 100644
index 0000000..c75938a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/debug_hud.cpp
@@ -0,0 +1,45 @@
+//
+// debug_hud.cpp
+// imguiex
+
+#include
+
+#include "debug_hud.h"
+#include "imgui.h"
+
+void DebugHUD_InitDefaults( DebugHUD *hud )
+{
+ hud->show_test_window = true;
+ hud->show_example_window = true;
+ hud->rotation_speed = 15.0f;
+
+ hud->cubeColor1[0] = 0.4f;
+ hud->cubeColor1[1] = 0.4f;
+ hud->cubeColor1[2] = 1.0f;
+ hud->cubeColor1[3] = 1.0f;
+
+ hud->cubeColor2[0] = 1.0f;
+ hud->cubeColor2[1] = 0.4f;
+ hud->cubeColor2[2] = 0.4f;
+ hud->cubeColor2[3] = 1.0f;
+}
+
+void DebugHUD_DoInterface( DebugHUD *hud )
+{
+ if (hud->show_test_window)
+ {
+ ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver );
+ ImGui::ShowTestWindow( &hud->show_test_window );
+ }
+
+ if (hud->show_example_window)
+ {
+ ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver );
+ ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver );
+ ImGui::Begin("Another Window", &hud->show_example_window);
+ ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1);
+ ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2);
+ ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f);
+ ImGui::End();
+ }
+}
diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h
new file mode 100644
index 0000000..17122f5
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/debug_hud.h
@@ -0,0 +1,25 @@
+//
+// debug_hud.h
+// imguiex
+
+#pragma once
+
+typedef struct DebugHUD
+{
+ bool show_test_window;
+ bool show_example_window;
+ float rotation_speed;
+ float cubeColor1[4];
+ float cubeColor2[4];
+} DebugHUD;
+
+#if __cplusplus
+extern "C" {
+#endif
+
+void DebugHUD_InitDefaults( DebugHUD *hud );
+void DebugHUD_DoInterface( DebugHUD *hud );
+
+#if __cplusplus
+}
+#endif
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore
new file mode 100644
index 0000000..8feda89
--- /dev/null
+++ b/examples/apple_example/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+imguiex.xcodeproj/project.xcworkspace/
+imguiex.xcodeproj/xcuserdata/
\ No newline at end of file
diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md
new file mode 100644
index 0000000..339f6bf
--- /dev/null
+++ b/examples/apple_example/README.md
@@ -0,0 +1,41 @@
+# iOS / OSX example
+
+## Introduction
+
+This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device.
+
+It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy.
+
+Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active.
+
+## How to Use on iOS
+
+* In Synergy, go to Preferences, and uncheck "Use SSL encryption"
+* Run the example app.
+* Tap the "servername" button in the corner
+* Enter the name or the IP of your synergy host
+* If you had previously connected to a server, you may need to kill and re-start the app.
+
+## How to Build on OSX
+
+* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh)
+* Run the command: `brew install glfw3`
+* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme
+* Click `Run` button
+
+## Notes and TODOs
+
+Things that would be nice but I didn't get around to doing:
+
+* iOS software keyboard not supported for text inputs
+* iOS hardware (bluetooth) keyboards not supported
+* Graceful disconnect/reconnect from uSynergy.
+* Copy/Paste not well-supported
+
+## C++ on iOS / OSX
+
+ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension.
+
+Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer.
+
+In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly.
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h
new file mode 100644
index 0000000..82f1542
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.h
@@ -0,0 +1,13 @@
+//
+// AppDelegate.h
+// imguiex
+
+#import
+
+@interface AppDelegate : UIResponder
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m
new file mode 100644
index 0000000..ab83101
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.m
@@ -0,0 +1,41 @@
+//
+// AppDelegate.m
+// imguiex
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Override point for customization after application launch.
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
new file mode 100644
index 0000000..5717c00
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..90dfb2e
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h
new file mode 100644
index 0000000..3323cfd
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.h
@@ -0,0 +1,12 @@
+//
+// GameViewController.h
+// imguiex
+
+// This is the OpenGL Example template from XCode, modified to support ImGui
+
+#import
+#import
+
+@interface GameViewController : GLKViewController
+
+@end
diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m
new file mode 100644
index 0000000..e902f7a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.m
@@ -0,0 +1,481 @@
+//
+// GameViewController.m
+// imguiex
+//
+#import "GameViewController.h"
+#import
+
+#import "imgui_impl_ios.h"
+#import "debug_hud.h"
+
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
+
+#define SERVERNAME_KEY @"ServerName"
+
+#define SERVERNAME_ALERT_TAG (10)
+
+// Uniform index.
+enum
+{
+ UNIFORM_MODELVIEWPROJECTION_MATRIX,
+ UNIFORM_NORMAL_MATRIX,
+ UNIFORM_DIFFUSE_COLOR,
+
+ NUM_UNIFORMS
+};
+GLint uniforms[NUM_UNIFORMS];
+
+// Attribute index.
+enum
+{
+ ATTRIB_VERTEX,
+ ATTRIB_NORMAL,
+ NUM_ATTRIBUTES
+};
+
+GLfloat gCubeVertexData[216] =
+{
+ // Data layout for each line below is:
+ // positionX, positionY, positionZ, normalX, normalY, normalZ,
+ 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+
+ 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+
+ -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+
+ -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+
+ 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+
+ 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f
+};
+
+@interface GameViewController ()
+{
+ GLuint _program;
+
+ GLKMatrix4 _modelViewProjectionMatrix;
+ GLKMatrix3 _normalMatrix;
+ float _rotation;
+
+ GLuint _vertexArray;
+ GLuint _vertexBuffer;
+
+ DebugHUD _hud;
+}
+@property (strong, nonatomic) EAGLContext *context;
+@property (strong, nonatomic) GLKBaseEffect *effect;
+@property (strong, nonatomic) ImGuiHelper *imgui;
+@property (weak, nonatomic) IBOutlet UIButton *btnServername;
+
+@property (strong, nonatomic) NSString *serverName;
+
+- (IBAction)onServernameTapped:(id)sender;
+
+- (void)setupGL;
+- (void)tearDownGL;
+
+- (BOOL)loadShaders;
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file;
+- (BOOL)linkProgram:(GLuint)prog;
+- (BOOL)validateProgram:(GLuint)prog;
+@end
+
+@implementation GameViewController
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+
+ if (!self.context) {
+ NSLog(@"Failed to create ES context");
+ }
+
+ GLKView *view = (GLKView *)self.view;
+ view.context = self.context;
+ view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
+
+ [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
+
+ [self setupGL];
+
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ];
+ self.imgui = [[ImGuiHelper alloc] initWithView:self.view ];
+ if (self.serverName)
+ {
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+ [self.imgui connectServer: self.serverName ];
+ }
+
+ DebugHUD_InitDefaults( &_hud );
+}
+
+- (void)dealloc
+{
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+
+ if ([self isViewLoaded] && ([[self view] window] == nil)) {
+ self.view = nil;
+
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+ self.context = nil;
+ }
+
+ // Dispose of any resources that can be recreated.
+}
+
+
+- (BOOL)prefersStatusBarHidden {
+ return YES;
+}
+
+- (IBAction)onServernameTapped:(id)sender
+{
+ UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ];
+ alert.alertViewStyle = UIAlertViewStylePlainTextInput;
+ alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to
+ [alert show];
+}
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG))
+ {
+ // This is really janky. I usually just hardcode the servername since I'm building it anyway.
+ // If you want to properly handle updating the server, you'll want to tear down and recreate
+ // the usynergy stuff in connectServer
+ BOOL serverNameWasSet = self.serverName.length > 0;
+ NSString *serverName = [[alertView textFieldAtIndex:0] text];
+
+ if ([serverName length] > 0) {
+ self.serverName = serverName;
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ [userDefaults setObject:serverName forKey:SERVERNAME_KEY ];
+ [userDefaults synchronize];
+
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+
+ // If we hadn't previously connected, try now
+ if (!serverNameWasSet) {
+ [self.imgui connectServer:self.serverName];
+ }
+ else
+ {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated"
+ message:@"Restart the app to connect the server"
+ delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
+ [alert show];
+ }
+ }
+ }
+}
+
+- (void)setupGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ [self loadShaders];
+
+ self.effect = [[GLKBaseEffect alloc] init];
+ self.effect.light0.enabled = GL_TRUE;
+ self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f);
+
+ glEnable(GL_DEPTH_TEST);
+
+ glGenVertexArraysOES(1, &_vertexArray);
+ glBindVertexArrayOES(_vertexArray);
+
+ glGenBuffers(1, &_vertexBuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);
+
+ glEnableVertexAttribArray(GLKVertexAttribPosition);
+ glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
+ glEnableVertexAttribArray(GLKVertexAttribNormal);
+ glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
+
+ glBindVertexArrayOES(0);
+
+
+}
+
+- (void)tearDownGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ glDeleteBuffers(1, &_vertexBuffer);
+ glDeleteVertexArraysOES(1, &_vertexArray);
+
+ self.effect = nil;
+
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+}
+
+#pragma mark - GLKView and GLKViewController delegate methods
+
+- (void)update
+{
+ float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height);
+ GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
+
+ self.effect.transform.projectionMatrix = projectionMatrix;
+
+ GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);
+ baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
+
+ // Compute the model view matrix for the object rendered with GLKit
+ GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ self.effect.transform.modelviewMatrix = modelViewMatrix;
+
+ // Compute the model view matrix for the object rendered with ES2
+ modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
+
+ _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
+
+ _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0));
+}
+
+
+- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
+{
+ glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glBindVertexArrayOES(_vertexArray);
+
+ // Render the object with GLKit
+ [self.effect prepareToDraw];
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ // Render the object again with ES2
+ glUseProgram(_program);
+
+ glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
+ glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
+ glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] );
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ [self.imgui newFrame];
+
+ // Now do our ImGUI UI
+ DebugHUD_DoInterface( &_hud );
+
+ self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f);
+
+ // Now render Imgui
+ [self.imgui render];
+
+}
+
+#pragma mark - OpenGL ES 2 shader compilation
+
+- (BOOL)loadShaders
+{
+ GLuint vertShader, fragShader;
+ NSString *vertShaderPathname, *fragShaderPathname;
+
+ // Create shader program.
+ _program = glCreateProgram();
+
+ // Create and compile vertex shader.
+ vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
+ if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
+ NSLog(@"Failed to compile vertex shader");
+ return NO;
+ }
+
+ // Create and compile fragment shader.
+ fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
+ if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
+ NSLog(@"Failed to compile fragment shader");
+ return NO;
+ }
+
+ // Attach vertex shader to program.
+ glAttachShader(_program, vertShader);
+
+ // Attach fragment shader to program.
+ glAttachShader(_program, fragShader);
+
+ // Bind attribute locations.
+ // This needs to be done prior to linking.
+ glBindAttribLocation(_program, GLKVertexAttribPosition, "position");
+ glBindAttribLocation(_program, GLKVertexAttribNormal, "normal");
+
+ // Link program.
+ if (![self linkProgram:_program]) {
+ NSLog(@"Failed to link program: %d", _program);
+
+ if (vertShader) {
+ glDeleteShader(vertShader);
+ vertShader = 0;
+ }
+ if (fragShader) {
+ glDeleteShader(fragShader);
+ fragShader = 0;
+ }
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+
+ return NO;
+ }
+
+ // Get uniform locations.
+ uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix");
+ uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix");
+ uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor");
+
+ // Release vertex and fragment shaders.
+ if (vertShader) {
+ glDetachShader(_program, vertShader);
+ glDeleteShader(vertShader);
+ }
+ if (fragShader) {
+ glDetachShader(_program, fragShader);
+ glDeleteShader(fragShader);
+ }
+
+ return YES;
+}
+
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
+{
+ GLint status;
+ const GLchar *source;
+
+ source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
+ if (!source) {
+ NSLog(@"Failed to load vertex shader");
+ return NO;
+ }
+
+ *shader = glCreateShader(type);
+ glShaderSource(*shader, 1, &source, NULL);
+ glCompileShader(*shader);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(*shader, logLength, &logLength, log);
+ NSLog(@"Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
+ if (status == 0) {
+ glDeleteShader(*shader);
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)linkProgram:(GLuint)prog
+{
+ GLint status;
+ glLinkProgram(prog);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program link log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetProgramiv(prog, GL_LINK_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)validateProgram:(GLuint)prog
+{
+ GLint logLength, status;
+
+ glValidateProgram(prog);
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program validate log:\n%s", log);
+ free(log);
+ }
+
+ glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..06b60d8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,77 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@2x~iphone.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@3x~iphone.png",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76~ipad.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76@2x~ipad.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "83.5x83.5",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
new file mode 100644
index 0000000..d728bc3
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
new file mode 100644
index 0000000..f48b799
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
new file mode 100644
index 0000000..67b08b8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
new file mode 100644
index 0000000..ae88e04
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist
new file mode 100644
index 0000000..bc6f548
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Info.plist
@@ -0,0 +1,49 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ org.imgui.example.$(PRODUCT_NAME:rfc1034identifier)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UIStatusBarHidden
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh
new file mode 100644
index 0000000..4000524
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh
@@ -0,0 +1,10 @@
+//
+// Shader.fsh
+// imguiex
+
+varying lowp vec4 colorVarying;
+
+void main()
+{
+ gl_FragColor = colorVarying;
+}
diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh
new file mode 100644
index 0000000..313c3d7
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh
@@ -0,0 +1,25 @@
+//
+// Shader.vsh
+// imguiex
+
+attribute vec4 position;
+attribute vec3 normal;
+
+varying lowp vec4 colorVarying;
+
+uniform vec3 diffuseColor;
+uniform mat4 modelViewProjectionMatrix;
+uniform mat3 normalMatrix;
+
+void main()
+{
+ vec3 eyeNormal = normalize(normalMatrix * normal);
+ vec3 lightPosition = vec3(0.0, 0.0, 1.0);
+
+ float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition)));
+
+ vec3 colorLit = diffuseColor * nDotVP;
+ colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 );
+
+ gl_Position = modelViewProjectionMatrix * position;
+}
diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp
new file mode 100644
index 0000000..c75938a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/debug_hud.cpp
@@ -0,0 +1,45 @@
+//
+// debug_hud.cpp
+// imguiex
+
+#include
+
+#include "debug_hud.h"
+#include "imgui.h"
+
+void DebugHUD_InitDefaults( DebugHUD *hud )
+{
+ hud->show_test_window = true;
+ hud->show_example_window = true;
+ hud->rotation_speed = 15.0f;
+
+ hud->cubeColor1[0] = 0.4f;
+ hud->cubeColor1[1] = 0.4f;
+ hud->cubeColor1[2] = 1.0f;
+ hud->cubeColor1[3] = 1.0f;
+
+ hud->cubeColor2[0] = 1.0f;
+ hud->cubeColor2[1] = 0.4f;
+ hud->cubeColor2[2] = 0.4f;
+ hud->cubeColor2[3] = 1.0f;
+}
+
+void DebugHUD_DoInterface( DebugHUD *hud )
+{
+ if (hud->show_test_window)
+ {
+ ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver );
+ ImGui::ShowTestWindow( &hud->show_test_window );
+ }
+
+ if (hud->show_example_window)
+ {
+ ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver );
+ ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver );
+ ImGui::Begin("Another Window", &hud->show_example_window);
+ ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1);
+ ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2);
+ ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f);
+ ImGui::End();
+ }
+}
diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h
new file mode 100644
index 0000000..17122f5
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/debug_hud.h
@@ -0,0 +1,25 @@
+//
+// debug_hud.h
+// imguiex
+
+#pragma once
+
+typedef struct DebugHUD
+{
+ bool show_test_window;
+ bool show_example_window;
+ float rotation_speed;
+ float cubeColor1[4];
+ float cubeColor2[4];
+} DebugHUD;
+
+#if __cplusplus
+extern "C" {
+#endif
+
+void DebugHUD_InitDefaults( DebugHUD *hud );
+void DebugHUD_DoInterface( DebugHUD *hud );
+
+#if __cplusplus
+}
+#endif
diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png
new file mode 100644
index 0000000..820e4d7
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png
Binary files differ
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore
new file mode 100644
index 0000000..8feda89
--- /dev/null
+++ b/examples/apple_example/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+imguiex.xcodeproj/project.xcworkspace/
+imguiex.xcodeproj/xcuserdata/
\ No newline at end of file
diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md
new file mode 100644
index 0000000..339f6bf
--- /dev/null
+++ b/examples/apple_example/README.md
@@ -0,0 +1,41 @@
+# iOS / OSX example
+
+## Introduction
+
+This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device.
+
+It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy.
+
+Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active.
+
+## How to Use on iOS
+
+* In Synergy, go to Preferences, and uncheck "Use SSL encryption"
+* Run the example app.
+* Tap the "servername" button in the corner
+* Enter the name or the IP of your synergy host
+* If you had previously connected to a server, you may need to kill and re-start the app.
+
+## How to Build on OSX
+
+* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh)
+* Run the command: `brew install glfw3`
+* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme
+* Click `Run` button
+
+## Notes and TODOs
+
+Things that would be nice but I didn't get around to doing:
+
+* iOS software keyboard not supported for text inputs
+* iOS hardware (bluetooth) keyboards not supported
+* Graceful disconnect/reconnect from uSynergy.
+* Copy/Paste not well-supported
+
+## C++ on iOS / OSX
+
+ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension.
+
+Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer.
+
+In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly.
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h
new file mode 100644
index 0000000..82f1542
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.h
@@ -0,0 +1,13 @@
+//
+// AppDelegate.h
+// imguiex
+
+#import
+
+@interface AppDelegate : UIResponder
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m
new file mode 100644
index 0000000..ab83101
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.m
@@ -0,0 +1,41 @@
+//
+// AppDelegate.m
+// imguiex
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Override point for customization after application launch.
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
new file mode 100644
index 0000000..5717c00
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..90dfb2e
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h
new file mode 100644
index 0000000..3323cfd
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.h
@@ -0,0 +1,12 @@
+//
+// GameViewController.h
+// imguiex
+
+// This is the OpenGL Example template from XCode, modified to support ImGui
+
+#import
+#import
+
+@interface GameViewController : GLKViewController
+
+@end
diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m
new file mode 100644
index 0000000..e902f7a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.m
@@ -0,0 +1,481 @@
+//
+// GameViewController.m
+// imguiex
+//
+#import "GameViewController.h"
+#import
+
+#import "imgui_impl_ios.h"
+#import "debug_hud.h"
+
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
+
+#define SERVERNAME_KEY @"ServerName"
+
+#define SERVERNAME_ALERT_TAG (10)
+
+// Uniform index.
+enum
+{
+ UNIFORM_MODELVIEWPROJECTION_MATRIX,
+ UNIFORM_NORMAL_MATRIX,
+ UNIFORM_DIFFUSE_COLOR,
+
+ NUM_UNIFORMS
+};
+GLint uniforms[NUM_UNIFORMS];
+
+// Attribute index.
+enum
+{
+ ATTRIB_VERTEX,
+ ATTRIB_NORMAL,
+ NUM_ATTRIBUTES
+};
+
+GLfloat gCubeVertexData[216] =
+{
+ // Data layout for each line below is:
+ // positionX, positionY, positionZ, normalX, normalY, normalZ,
+ 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+
+ 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+
+ -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+
+ -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+
+ 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+
+ 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f
+};
+
+@interface GameViewController ()
+{
+ GLuint _program;
+
+ GLKMatrix4 _modelViewProjectionMatrix;
+ GLKMatrix3 _normalMatrix;
+ float _rotation;
+
+ GLuint _vertexArray;
+ GLuint _vertexBuffer;
+
+ DebugHUD _hud;
+}
+@property (strong, nonatomic) EAGLContext *context;
+@property (strong, nonatomic) GLKBaseEffect *effect;
+@property (strong, nonatomic) ImGuiHelper *imgui;
+@property (weak, nonatomic) IBOutlet UIButton *btnServername;
+
+@property (strong, nonatomic) NSString *serverName;
+
+- (IBAction)onServernameTapped:(id)sender;
+
+- (void)setupGL;
+- (void)tearDownGL;
+
+- (BOOL)loadShaders;
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file;
+- (BOOL)linkProgram:(GLuint)prog;
+- (BOOL)validateProgram:(GLuint)prog;
+@end
+
+@implementation GameViewController
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+
+ if (!self.context) {
+ NSLog(@"Failed to create ES context");
+ }
+
+ GLKView *view = (GLKView *)self.view;
+ view.context = self.context;
+ view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
+
+ [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
+
+ [self setupGL];
+
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ];
+ self.imgui = [[ImGuiHelper alloc] initWithView:self.view ];
+ if (self.serverName)
+ {
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+ [self.imgui connectServer: self.serverName ];
+ }
+
+ DebugHUD_InitDefaults( &_hud );
+}
+
+- (void)dealloc
+{
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+
+ if ([self isViewLoaded] && ([[self view] window] == nil)) {
+ self.view = nil;
+
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+ self.context = nil;
+ }
+
+ // Dispose of any resources that can be recreated.
+}
+
+
+- (BOOL)prefersStatusBarHidden {
+ return YES;
+}
+
+- (IBAction)onServernameTapped:(id)sender
+{
+ UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ];
+ alert.alertViewStyle = UIAlertViewStylePlainTextInput;
+ alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to
+ [alert show];
+}
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG))
+ {
+ // This is really janky. I usually just hardcode the servername since I'm building it anyway.
+ // If you want to properly handle updating the server, you'll want to tear down and recreate
+ // the usynergy stuff in connectServer
+ BOOL serverNameWasSet = self.serverName.length > 0;
+ NSString *serverName = [[alertView textFieldAtIndex:0] text];
+
+ if ([serverName length] > 0) {
+ self.serverName = serverName;
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ [userDefaults setObject:serverName forKey:SERVERNAME_KEY ];
+ [userDefaults synchronize];
+
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+
+ // If we hadn't previously connected, try now
+ if (!serverNameWasSet) {
+ [self.imgui connectServer:self.serverName];
+ }
+ else
+ {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated"
+ message:@"Restart the app to connect the server"
+ delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
+ [alert show];
+ }
+ }
+ }
+}
+
+- (void)setupGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ [self loadShaders];
+
+ self.effect = [[GLKBaseEffect alloc] init];
+ self.effect.light0.enabled = GL_TRUE;
+ self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f);
+
+ glEnable(GL_DEPTH_TEST);
+
+ glGenVertexArraysOES(1, &_vertexArray);
+ glBindVertexArrayOES(_vertexArray);
+
+ glGenBuffers(1, &_vertexBuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);
+
+ glEnableVertexAttribArray(GLKVertexAttribPosition);
+ glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
+ glEnableVertexAttribArray(GLKVertexAttribNormal);
+ glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
+
+ glBindVertexArrayOES(0);
+
+
+}
+
+- (void)tearDownGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ glDeleteBuffers(1, &_vertexBuffer);
+ glDeleteVertexArraysOES(1, &_vertexArray);
+
+ self.effect = nil;
+
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+}
+
+#pragma mark - GLKView and GLKViewController delegate methods
+
+- (void)update
+{
+ float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height);
+ GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
+
+ self.effect.transform.projectionMatrix = projectionMatrix;
+
+ GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);
+ baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
+
+ // Compute the model view matrix for the object rendered with GLKit
+ GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ self.effect.transform.modelviewMatrix = modelViewMatrix;
+
+ // Compute the model view matrix for the object rendered with ES2
+ modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
+
+ _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
+
+ _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0));
+}
+
+
+- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
+{
+ glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glBindVertexArrayOES(_vertexArray);
+
+ // Render the object with GLKit
+ [self.effect prepareToDraw];
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ // Render the object again with ES2
+ glUseProgram(_program);
+
+ glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
+ glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
+ glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] );
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ [self.imgui newFrame];
+
+ // Now do our ImGUI UI
+ DebugHUD_DoInterface( &_hud );
+
+ self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f);
+
+ // Now render Imgui
+ [self.imgui render];
+
+}
+
+#pragma mark - OpenGL ES 2 shader compilation
+
+- (BOOL)loadShaders
+{
+ GLuint vertShader, fragShader;
+ NSString *vertShaderPathname, *fragShaderPathname;
+
+ // Create shader program.
+ _program = glCreateProgram();
+
+ // Create and compile vertex shader.
+ vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
+ if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
+ NSLog(@"Failed to compile vertex shader");
+ return NO;
+ }
+
+ // Create and compile fragment shader.
+ fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
+ if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
+ NSLog(@"Failed to compile fragment shader");
+ return NO;
+ }
+
+ // Attach vertex shader to program.
+ glAttachShader(_program, vertShader);
+
+ // Attach fragment shader to program.
+ glAttachShader(_program, fragShader);
+
+ // Bind attribute locations.
+ // This needs to be done prior to linking.
+ glBindAttribLocation(_program, GLKVertexAttribPosition, "position");
+ glBindAttribLocation(_program, GLKVertexAttribNormal, "normal");
+
+ // Link program.
+ if (![self linkProgram:_program]) {
+ NSLog(@"Failed to link program: %d", _program);
+
+ if (vertShader) {
+ glDeleteShader(vertShader);
+ vertShader = 0;
+ }
+ if (fragShader) {
+ glDeleteShader(fragShader);
+ fragShader = 0;
+ }
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+
+ return NO;
+ }
+
+ // Get uniform locations.
+ uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix");
+ uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix");
+ uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor");
+
+ // Release vertex and fragment shaders.
+ if (vertShader) {
+ glDetachShader(_program, vertShader);
+ glDeleteShader(vertShader);
+ }
+ if (fragShader) {
+ glDetachShader(_program, fragShader);
+ glDeleteShader(fragShader);
+ }
+
+ return YES;
+}
+
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
+{
+ GLint status;
+ const GLchar *source;
+
+ source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
+ if (!source) {
+ NSLog(@"Failed to load vertex shader");
+ return NO;
+ }
+
+ *shader = glCreateShader(type);
+ glShaderSource(*shader, 1, &source, NULL);
+ glCompileShader(*shader);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(*shader, logLength, &logLength, log);
+ NSLog(@"Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
+ if (status == 0) {
+ glDeleteShader(*shader);
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)linkProgram:(GLuint)prog
+{
+ GLint status;
+ glLinkProgram(prog);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program link log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetProgramiv(prog, GL_LINK_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)validateProgram:(GLuint)prog
+{
+ GLint logLength, status;
+
+ glValidateProgram(prog);
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program validate log:\n%s", log);
+ free(log);
+ }
+
+ glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..06b60d8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,77 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@2x~iphone.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@3x~iphone.png",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76~ipad.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76@2x~ipad.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "83.5x83.5",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
new file mode 100644
index 0000000..d728bc3
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
new file mode 100644
index 0000000..f48b799
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
new file mode 100644
index 0000000..67b08b8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
new file mode 100644
index 0000000..ae88e04
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist
new file mode 100644
index 0000000..bc6f548
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Info.plist
@@ -0,0 +1,49 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ org.imgui.example.$(PRODUCT_NAME:rfc1034identifier)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UIStatusBarHidden
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh
new file mode 100644
index 0000000..4000524
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh
@@ -0,0 +1,10 @@
+//
+// Shader.fsh
+// imguiex
+
+varying lowp vec4 colorVarying;
+
+void main()
+{
+ gl_FragColor = colorVarying;
+}
diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh
new file mode 100644
index 0000000..313c3d7
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh
@@ -0,0 +1,25 @@
+//
+// Shader.vsh
+// imguiex
+
+attribute vec4 position;
+attribute vec3 normal;
+
+varying lowp vec4 colorVarying;
+
+uniform vec3 diffuseColor;
+uniform mat4 modelViewProjectionMatrix;
+uniform mat3 normalMatrix;
+
+void main()
+{
+ vec3 eyeNormal = normalize(normalMatrix * normal);
+ vec3 lightPosition = vec3(0.0, 0.0, 1.0);
+
+ float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition)));
+
+ vec3 colorLit = diffuseColor * nDotVP;
+ colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 );
+
+ gl_Position = modelViewProjectionMatrix * position;
+}
diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp
new file mode 100644
index 0000000..c75938a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/debug_hud.cpp
@@ -0,0 +1,45 @@
+//
+// debug_hud.cpp
+// imguiex
+
+#include
+
+#include "debug_hud.h"
+#include "imgui.h"
+
+void DebugHUD_InitDefaults( DebugHUD *hud )
+{
+ hud->show_test_window = true;
+ hud->show_example_window = true;
+ hud->rotation_speed = 15.0f;
+
+ hud->cubeColor1[0] = 0.4f;
+ hud->cubeColor1[1] = 0.4f;
+ hud->cubeColor1[2] = 1.0f;
+ hud->cubeColor1[3] = 1.0f;
+
+ hud->cubeColor2[0] = 1.0f;
+ hud->cubeColor2[1] = 0.4f;
+ hud->cubeColor2[2] = 0.4f;
+ hud->cubeColor2[3] = 1.0f;
+}
+
+void DebugHUD_DoInterface( DebugHUD *hud )
+{
+ if (hud->show_test_window)
+ {
+ ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver );
+ ImGui::ShowTestWindow( &hud->show_test_window );
+ }
+
+ if (hud->show_example_window)
+ {
+ ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver );
+ ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver );
+ ImGui::Begin("Another Window", &hud->show_example_window);
+ ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1);
+ ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2);
+ ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f);
+ ImGui::End();
+ }
+}
diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h
new file mode 100644
index 0000000..17122f5
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/debug_hud.h
@@ -0,0 +1,25 @@
+//
+// debug_hud.h
+// imguiex
+
+#pragma once
+
+typedef struct DebugHUD
+{
+ bool show_test_window;
+ bool show_example_window;
+ float rotation_speed;
+ float cubeColor1[4];
+ float cubeColor2[4];
+} DebugHUD;
+
+#if __cplusplus
+extern "C" {
+#endif
+
+void DebugHUD_InitDefaults( DebugHUD *hud );
+void DebugHUD_DoInterface( DebugHUD *hud );
+
+#if __cplusplus
+}
+#endif
diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png
new file mode 100644
index 0000000..820e4d7
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h
new file mode 100644
index 0000000..9b01dd3
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h
@@ -0,0 +1,22 @@
+// ImGui iOS+OpenGL+Synergy binding
+// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much.
+// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application.
+
+// by Joel Davis (joeld42@gmail.com)
+
+#pragma once
+
+#include
+#include
+
+@interface ImGuiHelper : NSObject
+
+- (id) initWithView: (UIView *)view;
+
+- (void)connectServer: (NSString*)serverName;
+
+- (void)render;
+- (void)newFrame;
+
+@end
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore
new file mode 100644
index 0000000..8feda89
--- /dev/null
+++ b/examples/apple_example/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+imguiex.xcodeproj/project.xcworkspace/
+imguiex.xcodeproj/xcuserdata/
\ No newline at end of file
diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md
new file mode 100644
index 0000000..339f6bf
--- /dev/null
+++ b/examples/apple_example/README.md
@@ -0,0 +1,41 @@
+# iOS / OSX example
+
+## Introduction
+
+This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device.
+
+It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy.
+
+Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active.
+
+## How to Use on iOS
+
+* In Synergy, go to Preferences, and uncheck "Use SSL encryption"
+* Run the example app.
+* Tap the "servername" button in the corner
+* Enter the name or the IP of your synergy host
+* If you had previously connected to a server, you may need to kill and re-start the app.
+
+## How to Build on OSX
+
+* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh)
+* Run the command: `brew install glfw3`
+* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme
+* Click `Run` button
+
+## Notes and TODOs
+
+Things that would be nice but I didn't get around to doing:
+
+* iOS software keyboard not supported for text inputs
+* iOS hardware (bluetooth) keyboards not supported
+* Graceful disconnect/reconnect from uSynergy.
+* Copy/Paste not well-supported
+
+## C++ on iOS / OSX
+
+ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension.
+
+Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer.
+
+In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly.
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h
new file mode 100644
index 0000000..82f1542
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.h
@@ -0,0 +1,13 @@
+//
+// AppDelegate.h
+// imguiex
+
+#import
+
+@interface AppDelegate : UIResponder
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m
new file mode 100644
index 0000000..ab83101
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.m
@@ -0,0 +1,41 @@
+//
+// AppDelegate.m
+// imguiex
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Override point for customization after application launch.
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
new file mode 100644
index 0000000..5717c00
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..90dfb2e
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h
new file mode 100644
index 0000000..3323cfd
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.h
@@ -0,0 +1,12 @@
+//
+// GameViewController.h
+// imguiex
+
+// This is the OpenGL Example template from XCode, modified to support ImGui
+
+#import
+#import
+
+@interface GameViewController : GLKViewController
+
+@end
diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m
new file mode 100644
index 0000000..e902f7a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.m
@@ -0,0 +1,481 @@
+//
+// GameViewController.m
+// imguiex
+//
+#import "GameViewController.h"
+#import
+
+#import "imgui_impl_ios.h"
+#import "debug_hud.h"
+
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
+
+#define SERVERNAME_KEY @"ServerName"
+
+#define SERVERNAME_ALERT_TAG (10)
+
+// Uniform index.
+enum
+{
+ UNIFORM_MODELVIEWPROJECTION_MATRIX,
+ UNIFORM_NORMAL_MATRIX,
+ UNIFORM_DIFFUSE_COLOR,
+
+ NUM_UNIFORMS
+};
+GLint uniforms[NUM_UNIFORMS];
+
+// Attribute index.
+enum
+{
+ ATTRIB_VERTEX,
+ ATTRIB_NORMAL,
+ NUM_ATTRIBUTES
+};
+
+GLfloat gCubeVertexData[216] =
+{
+ // Data layout for each line below is:
+ // positionX, positionY, positionZ, normalX, normalY, normalZ,
+ 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+
+ 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+
+ -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+
+ -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+
+ 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+
+ 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f
+};
+
+@interface GameViewController ()
+{
+ GLuint _program;
+
+ GLKMatrix4 _modelViewProjectionMatrix;
+ GLKMatrix3 _normalMatrix;
+ float _rotation;
+
+ GLuint _vertexArray;
+ GLuint _vertexBuffer;
+
+ DebugHUD _hud;
+}
+@property (strong, nonatomic) EAGLContext *context;
+@property (strong, nonatomic) GLKBaseEffect *effect;
+@property (strong, nonatomic) ImGuiHelper *imgui;
+@property (weak, nonatomic) IBOutlet UIButton *btnServername;
+
+@property (strong, nonatomic) NSString *serverName;
+
+- (IBAction)onServernameTapped:(id)sender;
+
+- (void)setupGL;
+- (void)tearDownGL;
+
+- (BOOL)loadShaders;
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file;
+- (BOOL)linkProgram:(GLuint)prog;
+- (BOOL)validateProgram:(GLuint)prog;
+@end
+
+@implementation GameViewController
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+
+ if (!self.context) {
+ NSLog(@"Failed to create ES context");
+ }
+
+ GLKView *view = (GLKView *)self.view;
+ view.context = self.context;
+ view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
+
+ [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
+
+ [self setupGL];
+
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ];
+ self.imgui = [[ImGuiHelper alloc] initWithView:self.view ];
+ if (self.serverName)
+ {
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+ [self.imgui connectServer: self.serverName ];
+ }
+
+ DebugHUD_InitDefaults( &_hud );
+}
+
+- (void)dealloc
+{
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+
+ if ([self isViewLoaded] && ([[self view] window] == nil)) {
+ self.view = nil;
+
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+ self.context = nil;
+ }
+
+ // Dispose of any resources that can be recreated.
+}
+
+
+- (BOOL)prefersStatusBarHidden {
+ return YES;
+}
+
+- (IBAction)onServernameTapped:(id)sender
+{
+ UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ];
+ alert.alertViewStyle = UIAlertViewStylePlainTextInput;
+ alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to
+ [alert show];
+}
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG))
+ {
+ // This is really janky. I usually just hardcode the servername since I'm building it anyway.
+ // If you want to properly handle updating the server, you'll want to tear down and recreate
+ // the usynergy stuff in connectServer
+ BOOL serverNameWasSet = self.serverName.length > 0;
+ NSString *serverName = [[alertView textFieldAtIndex:0] text];
+
+ if ([serverName length] > 0) {
+ self.serverName = serverName;
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ [userDefaults setObject:serverName forKey:SERVERNAME_KEY ];
+ [userDefaults synchronize];
+
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+
+ // If we hadn't previously connected, try now
+ if (!serverNameWasSet) {
+ [self.imgui connectServer:self.serverName];
+ }
+ else
+ {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated"
+ message:@"Restart the app to connect the server"
+ delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
+ [alert show];
+ }
+ }
+ }
+}
+
+- (void)setupGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ [self loadShaders];
+
+ self.effect = [[GLKBaseEffect alloc] init];
+ self.effect.light0.enabled = GL_TRUE;
+ self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f);
+
+ glEnable(GL_DEPTH_TEST);
+
+ glGenVertexArraysOES(1, &_vertexArray);
+ glBindVertexArrayOES(_vertexArray);
+
+ glGenBuffers(1, &_vertexBuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);
+
+ glEnableVertexAttribArray(GLKVertexAttribPosition);
+ glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
+ glEnableVertexAttribArray(GLKVertexAttribNormal);
+ glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
+
+ glBindVertexArrayOES(0);
+
+
+}
+
+- (void)tearDownGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ glDeleteBuffers(1, &_vertexBuffer);
+ glDeleteVertexArraysOES(1, &_vertexArray);
+
+ self.effect = nil;
+
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+}
+
+#pragma mark - GLKView and GLKViewController delegate methods
+
+- (void)update
+{
+ float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height);
+ GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
+
+ self.effect.transform.projectionMatrix = projectionMatrix;
+
+ GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);
+ baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
+
+ // Compute the model view matrix for the object rendered with GLKit
+ GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ self.effect.transform.modelviewMatrix = modelViewMatrix;
+
+ // Compute the model view matrix for the object rendered with ES2
+ modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
+
+ _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
+
+ _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0));
+}
+
+
+- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
+{
+ glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glBindVertexArrayOES(_vertexArray);
+
+ // Render the object with GLKit
+ [self.effect prepareToDraw];
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ // Render the object again with ES2
+ glUseProgram(_program);
+
+ glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
+ glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
+ glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] );
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ [self.imgui newFrame];
+
+ // Now do our ImGUI UI
+ DebugHUD_DoInterface( &_hud );
+
+ self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f);
+
+ // Now render Imgui
+ [self.imgui render];
+
+}
+
+#pragma mark - OpenGL ES 2 shader compilation
+
+- (BOOL)loadShaders
+{
+ GLuint vertShader, fragShader;
+ NSString *vertShaderPathname, *fragShaderPathname;
+
+ // Create shader program.
+ _program = glCreateProgram();
+
+ // Create and compile vertex shader.
+ vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
+ if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
+ NSLog(@"Failed to compile vertex shader");
+ return NO;
+ }
+
+ // Create and compile fragment shader.
+ fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
+ if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
+ NSLog(@"Failed to compile fragment shader");
+ return NO;
+ }
+
+ // Attach vertex shader to program.
+ glAttachShader(_program, vertShader);
+
+ // Attach fragment shader to program.
+ glAttachShader(_program, fragShader);
+
+ // Bind attribute locations.
+ // This needs to be done prior to linking.
+ glBindAttribLocation(_program, GLKVertexAttribPosition, "position");
+ glBindAttribLocation(_program, GLKVertexAttribNormal, "normal");
+
+ // Link program.
+ if (![self linkProgram:_program]) {
+ NSLog(@"Failed to link program: %d", _program);
+
+ if (vertShader) {
+ glDeleteShader(vertShader);
+ vertShader = 0;
+ }
+ if (fragShader) {
+ glDeleteShader(fragShader);
+ fragShader = 0;
+ }
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+
+ return NO;
+ }
+
+ // Get uniform locations.
+ uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix");
+ uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix");
+ uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor");
+
+ // Release vertex and fragment shaders.
+ if (vertShader) {
+ glDetachShader(_program, vertShader);
+ glDeleteShader(vertShader);
+ }
+ if (fragShader) {
+ glDetachShader(_program, fragShader);
+ glDeleteShader(fragShader);
+ }
+
+ return YES;
+}
+
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
+{
+ GLint status;
+ const GLchar *source;
+
+ source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
+ if (!source) {
+ NSLog(@"Failed to load vertex shader");
+ return NO;
+ }
+
+ *shader = glCreateShader(type);
+ glShaderSource(*shader, 1, &source, NULL);
+ glCompileShader(*shader);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(*shader, logLength, &logLength, log);
+ NSLog(@"Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
+ if (status == 0) {
+ glDeleteShader(*shader);
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)linkProgram:(GLuint)prog
+{
+ GLint status;
+ glLinkProgram(prog);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program link log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetProgramiv(prog, GL_LINK_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)validateProgram:(GLuint)prog
+{
+ GLint logLength, status;
+
+ glValidateProgram(prog);
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program validate log:\n%s", log);
+ free(log);
+ }
+
+ glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..06b60d8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,77 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@2x~iphone.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@3x~iphone.png",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76~ipad.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76@2x~ipad.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "83.5x83.5",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
new file mode 100644
index 0000000..d728bc3
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
new file mode 100644
index 0000000..f48b799
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
new file mode 100644
index 0000000..67b08b8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
new file mode 100644
index 0000000..ae88e04
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist
new file mode 100644
index 0000000..bc6f548
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Info.plist
@@ -0,0 +1,49 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ org.imgui.example.$(PRODUCT_NAME:rfc1034identifier)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UIStatusBarHidden
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh
new file mode 100644
index 0000000..4000524
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh
@@ -0,0 +1,10 @@
+//
+// Shader.fsh
+// imguiex
+
+varying lowp vec4 colorVarying;
+
+void main()
+{
+ gl_FragColor = colorVarying;
+}
diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh
new file mode 100644
index 0000000..313c3d7
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh
@@ -0,0 +1,25 @@
+//
+// Shader.vsh
+// imguiex
+
+attribute vec4 position;
+attribute vec3 normal;
+
+varying lowp vec4 colorVarying;
+
+uniform vec3 diffuseColor;
+uniform mat4 modelViewProjectionMatrix;
+uniform mat3 normalMatrix;
+
+void main()
+{
+ vec3 eyeNormal = normalize(normalMatrix * normal);
+ vec3 lightPosition = vec3(0.0, 0.0, 1.0);
+
+ float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition)));
+
+ vec3 colorLit = diffuseColor * nDotVP;
+ colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 );
+
+ gl_Position = modelViewProjectionMatrix * position;
+}
diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp
new file mode 100644
index 0000000..c75938a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/debug_hud.cpp
@@ -0,0 +1,45 @@
+//
+// debug_hud.cpp
+// imguiex
+
+#include
+
+#include "debug_hud.h"
+#include "imgui.h"
+
+void DebugHUD_InitDefaults( DebugHUD *hud )
+{
+ hud->show_test_window = true;
+ hud->show_example_window = true;
+ hud->rotation_speed = 15.0f;
+
+ hud->cubeColor1[0] = 0.4f;
+ hud->cubeColor1[1] = 0.4f;
+ hud->cubeColor1[2] = 1.0f;
+ hud->cubeColor1[3] = 1.0f;
+
+ hud->cubeColor2[0] = 1.0f;
+ hud->cubeColor2[1] = 0.4f;
+ hud->cubeColor2[2] = 0.4f;
+ hud->cubeColor2[3] = 1.0f;
+}
+
+void DebugHUD_DoInterface( DebugHUD *hud )
+{
+ if (hud->show_test_window)
+ {
+ ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver );
+ ImGui::ShowTestWindow( &hud->show_test_window );
+ }
+
+ if (hud->show_example_window)
+ {
+ ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver );
+ ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver );
+ ImGui::Begin("Another Window", &hud->show_example_window);
+ ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1);
+ ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2);
+ ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f);
+ ImGui::End();
+ }
+}
diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h
new file mode 100644
index 0000000..17122f5
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/debug_hud.h
@@ -0,0 +1,25 @@
+//
+// debug_hud.h
+// imguiex
+
+#pragma once
+
+typedef struct DebugHUD
+{
+ bool show_test_window;
+ bool show_example_window;
+ float rotation_speed;
+ float cubeColor1[4];
+ float cubeColor2[4];
+} DebugHUD;
+
+#if __cplusplus
+extern "C" {
+#endif
+
+void DebugHUD_InitDefaults( DebugHUD *hud );
+void DebugHUD_DoInterface( DebugHUD *hud );
+
+#if __cplusplus
+}
+#endif
diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png
new file mode 100644
index 0000000..820e4d7
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h
new file mode 100644
index 0000000..9b01dd3
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h
@@ -0,0 +1,22 @@
+// ImGui iOS+OpenGL+Synergy binding
+// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much.
+// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application.
+
+// by Joel Davis (joeld42@gmail.com)
+
+#pragma once
+
+#include
+#include
+
+@interface ImGuiHelper : NSObject
+
+- (id) initWithView: (UIView *)view;
+
+- (void)connectServer: (NSString*)serverName;
+
+- (void)render;
+- (void)newFrame;
+
+@end
diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm
new file mode 100644
index 0000000..893dbf9
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm
@@ -0,0 +1,806 @@
+// ImGui iOS+OpenGL+Synergy binding
+// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much.
+// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application.
+
+// TODO:
+// - Clipboard is not supported.
+
+#import
+#import
+
+#include
+#include
+#include
+#include
+
+#include "imgui_impl_ios.h"
+#include "imgui.h"
+
+#include "uSynergy.h"
+
+// From Carbon HIToolbox/Events.h
+// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247
+enum {
+ kVK_ANSI_A = 0x00,
+ kVK_ANSI_S = 0x01,
+ kVK_ANSI_D = 0x02,
+ kVK_ANSI_F = 0x03,
+ kVK_ANSI_H = 0x04,
+ kVK_ANSI_G = 0x05,
+ kVK_ANSI_Z = 0x06,
+ kVK_ANSI_X = 0x07,
+ kVK_ANSI_C = 0x08,
+ kVK_ANSI_V = 0x09,
+ kVK_ANSI_B = 0x0B,
+ kVK_ANSI_Q = 0x0C,
+ kVK_ANSI_W = 0x0D,
+ kVK_ANSI_E = 0x0E,
+ kVK_ANSI_R = 0x0F,
+ kVK_ANSI_Y = 0x10,
+ kVK_ANSI_T = 0x11,
+ kVK_ANSI_1 = 0x12,
+ kVK_ANSI_2 = 0x13,
+ kVK_ANSI_3 = 0x14,
+ kVK_ANSI_4 = 0x15,
+ kVK_ANSI_6 = 0x16,
+ kVK_ANSI_5 = 0x17,
+ kVK_ANSI_Equal = 0x18,
+ kVK_ANSI_9 = 0x19,
+ kVK_ANSI_7 = 0x1A,
+ kVK_ANSI_Minus = 0x1B,
+ kVK_ANSI_8 = 0x1C,
+ kVK_ANSI_0 = 0x1D,
+ kVK_ANSI_RightBracket = 0x1E,
+ kVK_ANSI_O = 0x1F,
+ kVK_ANSI_U = 0x20,
+ kVK_ANSI_LeftBracket = 0x21,
+ kVK_ANSI_I = 0x22,
+ kVK_ANSI_P = 0x23,
+ kVK_ANSI_L = 0x25,
+ kVK_ANSI_J = 0x26,
+ kVK_ANSI_Quote = 0x27,
+ kVK_ANSI_K = 0x28,
+ kVK_ANSI_Semicolon = 0x29,
+ kVK_ANSI_Backslash = 0x2A,
+ kVK_ANSI_Comma = 0x2B,
+ kVK_ANSI_Slash = 0x2C,
+ kVK_ANSI_N = 0x2D,
+ kVK_ANSI_M = 0x2E,
+ kVK_ANSI_Period = 0x2F,
+ kVK_ANSI_Grave = 0x32,
+ kVK_ANSI_KeypadDecimal = 0x41,
+ kVK_ANSI_KeypadMultiply = 0x43,
+ kVK_ANSI_KeypadPlus = 0x45,
+ kVK_ANSI_KeypadClear = 0x47,
+ kVK_ANSI_KeypadDivide = 0x4B,
+ kVK_ANSI_KeypadEnter = 0x4C,
+ kVK_ANSI_KeypadMinus = 0x4E,
+ kVK_ANSI_KeypadEquals = 0x51,
+ kVK_ANSI_Keypad0 = 0x52,
+ kVK_ANSI_Keypad1 = 0x53,
+ kVK_ANSI_Keypad2 = 0x54,
+ kVK_ANSI_Keypad3 = 0x55,
+ kVK_ANSI_Keypad4 = 0x56,
+ kVK_ANSI_Keypad5 = 0x57,
+ kVK_ANSI_Keypad6 = 0x58,
+ kVK_ANSI_Keypad7 = 0x59,
+ kVK_ANSI_Keypad8 = 0x5B,
+ kVK_ANSI_Keypad9 = 0x5C
+};
+
+/* keycodes for keys that are independent of keyboard layout*/
+enum {
+ kVK_Return = 0x24,
+ kVK_Tab = 0x30,
+ kVK_Space = 0x31,
+ kVK_Delete = 0x33,
+ kVK_Escape = 0x35,
+ kVK_Command = 0x37,
+ kVK_Shift = 0x38,
+ kVK_CapsLock = 0x39,
+ kVK_Option = 0x3A,
+ kVK_Control = 0x3B,
+ kVK_RightShift = 0x3C,
+ kVK_RightOption = 0x3D,
+ kVK_RightControl = 0x3E,
+ kVK_Function = 0x3F,
+ kVK_F17 = 0x40,
+ kVK_VolumeUp = 0x48,
+ kVK_VolumeDown = 0x49,
+ kVK_Mute = 0x4A,
+ kVK_F18 = 0x4F,
+ kVK_F19 = 0x50,
+ kVK_F20 = 0x5A,
+ kVK_F5 = 0x60,
+ kVK_F6 = 0x61,
+ kVK_F7 = 0x62,
+ kVK_F3 = 0x63,
+ kVK_F8 = 0x64,
+ kVK_F9 = 0x65,
+ kVK_F11 = 0x67,
+ kVK_F13 = 0x69,
+ kVK_F16 = 0x6A,
+ kVK_F14 = 0x6B,
+ kVK_F10 = 0x6D,
+ kVK_F12 = 0x6F,
+ kVK_F15 = 0x71,
+ kVK_Help = 0x72,
+ kVK_Home = 0x73,
+ kVK_PageUp = 0x74,
+ kVK_ForwardDelete = 0x75,
+ kVK_F4 = 0x76,
+ kVK_End = 0x77,
+ kVK_F2 = 0x78,
+ kVK_PageDown = 0x79,
+ kVK_F1 = 0x7A,
+ kVK_LeftArrow = 0x7B,
+ kVK_RightArrow = 0x7C,
+ kVK_DownArrow = 0x7D,
+ kVK_UpArrow = 0x7E
+};
+
+static char g_keycodeCharUnshifted[256] = {};
+static char g_keycodeCharShifted[256] = {};
+
+//static double g_Time = 0.0f;
+static bool g_MousePressed[3] = { false, false, false };
+static float g_mouseWheelX = 0.0f;
+static float g_mouseWheelY = 0.0f;
+
+static GLuint g_FontTexture = 0;
+static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0;
+static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0;
+static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0;
+static size_t g_VboSize = 0;
+static unsigned int g_VboHandle = 0, g_VaoHandle = 0;
+static float g_displayScale;
+
+static int usynergy_sockfd;
+static bool g_synergyPtrActive = false;
+static uint16_t g_mousePosX = 0;
+static uint16_t g_mousePosY = 0;
+
+static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data);
+bool ImGui_ImplIOS_CreateDeviceObjects();
+
+static NSString *g_serverName;
+
+uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie)
+{
+ // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since
+ // uSynergy does not support SSL.
+
+ NSLog( @"Connect Func!");
+ struct addrinfo hints, *res;
+
+ // first, load up address structs with getaddrinfo():
+ memset(&hints, 0, sizeof hints);
+ hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
+ hints.ai_socktype = SOCK_STREAM;
+
+ // get server address
+ getaddrinfo([g_serverName UTF8String], "24800", &hints, &res);
+
+ if (!res)
+ {
+ NSLog( @"Could not find server: %@", g_serverName );
+ return USYNERGY_FALSE;
+ }
+
+ // make a socket:
+ usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+
+ // connect it to the address and port we passed in to getaddrinfo():
+ int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen);
+ if (!ret) {
+ NSLog( @"Connect succeeded...");
+ } else {
+ NSLog( @"Connect failed, %d", ret );
+ }
+
+
+ return USYNERGY_TRUE;
+}
+
+uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length)
+{
+// NSLog( @"Send Func" );
+ send( usynergy_sockfd, buffer, length, 0 );
+
+ return USYNERGY_TRUE;
+}
+
+uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength)
+{
+ *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 );
+
+ return USYNERGY_TRUE;
+}
+
+void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs)
+{
+ usleep( timeMs * 1000 );
+}
+
+uint32_t ImGui_GetTimeFunc()
+{
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+
+ return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000);
+}
+
+void ImGui_TraceFunc(uSynergyCookie cookie, const char *text)
+{
+ puts(text);
+}
+
+void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active)
+{
+ g_synergyPtrActive = active;
+// printf( "Synergy: screen activate %s\n", active?"YES":"NO" );
+}
+
+void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY,
+ uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle)
+{
+// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY );
+ uSynergyContext *ctx = (uSynergyContext*)cookie;
+ g_mousePosX = x;
+ g_mousePosY = y;
+ g_mouseWheelX = wheelX;
+ g_mouseWheelY = wheelY;
+ g_MousePressed[0] = buttonLeft;
+ g_MousePressed[1] = buttonMiddle;
+ g_MousePressed[2] = buttonRight;
+
+ ctx->m_mouseWheelX = 0;
+ ctx->m_mouseWheelY = 0;
+}
+
+void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key,
+ uint16_t modifiers, uSynergyBool down, uSynergyBool repeat)
+{
+ int scanCode = key-1;
+// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false");
+ ImGuiIO& io = ImGui::GetIO();
+ io.KeysDown[key] = down;
+ io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT);
+ io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL);
+ io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT);
+ io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN);
+
+ // Add this as keyboard input
+ if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL))
+ {
+ // If this key maps to a character input, apply it
+ int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode];
+ io.AddInputCharacter((unsigned short)charForKeycode);
+ }
+
+}
+
+void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY)
+{
+ printf("Synergy: joystick callback TODO\n");
+}
+
+void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size)
+{
+ printf("Synergy: clipboard callback TODO\n" );
+}
+
+@interface ImGuiHelper ()
+{
+ BOOL _mouseDown;
+ BOOL _mouseTapped;
+ CGPoint _touchPos;
+
+ uSynergyContext _synergyCtx;
+ dispatch_queue_t _synergyQueue;
+}
+@property (nonatomic, weak) UIView *view;
+@property (nonatomic, strong) NSString *serverName;
+
+@end
+
+@implementation ImGuiHelper
+
+- (id) initWithView: (UIView *)view
+{
+ self = [super init];
+ if (self)
+ {
+ self.view = view;
+
+ [self setupImGuiHooks];
+ }
+ return self;
+}
+
+- (void)setupKeymaps
+{
+ // The keyboard mapping is a big headache. I tried for a while to find a better way to do this,
+ // but this was the best I could come up with. There are some device independent API's available
+ // to convert scan codes to unicode characters, but these are only available on mac and not
+ // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do
+ // this or any way to get the character codes out of usynergy.
+ g_keycodeCharUnshifted[ kVK_ANSI_A ]='a';
+ g_keycodeCharUnshifted[ kVK_ANSI_S ]='s';
+ g_keycodeCharUnshifted[ kVK_ANSI_D ]='d';
+ g_keycodeCharUnshifted[ kVK_ANSI_F ]='f';
+ g_keycodeCharUnshifted[ kVK_ANSI_H ]='h';
+ g_keycodeCharUnshifted[ kVK_ANSI_G ]='g';
+ g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z';
+ g_keycodeCharUnshifted[ kVK_ANSI_X ]='x';
+ g_keycodeCharUnshifted[ kVK_ANSI_C ]='c';
+ g_keycodeCharUnshifted[ kVK_ANSI_V ]='v';
+ g_keycodeCharUnshifted[ kVK_ANSI_B ]='b';
+ g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q';
+ g_keycodeCharUnshifted[ kVK_ANSI_W ]='w';
+ g_keycodeCharUnshifted[ kVK_ANSI_E ]='e';
+ g_keycodeCharUnshifted[ kVK_ANSI_R ]='r';
+ g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y';
+ g_keycodeCharUnshifted[ kVK_ANSI_T ]='t';
+ g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1';
+ g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2';
+ g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3';
+ g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4';
+ g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6';
+ g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5';
+ g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='=';
+ g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9';
+ g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7';
+ g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-';
+ g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8';
+ g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0';
+ g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']';
+ g_keycodeCharUnshifted[ kVK_ANSI_O ]='o';
+ g_keycodeCharUnshifted[ kVK_ANSI_U ]='u';
+ g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='[';
+ g_keycodeCharUnshifted[ kVK_ANSI_I ]='i';
+ g_keycodeCharUnshifted[ kVK_ANSI_P ]='p';
+ g_keycodeCharUnshifted[ kVK_ANSI_L ]='l';
+ g_keycodeCharUnshifted[ kVK_ANSI_J ]='j';
+ g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\'';
+ g_keycodeCharUnshifted[ kVK_ANSI_K ]='k';
+ g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';';
+ g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\';
+ g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=',';
+ g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/';
+ g_keycodeCharUnshifted[ kVK_ANSI_N ]='n';
+ g_keycodeCharUnshifted[ kVK_ANSI_M ]='m';
+ g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.';
+ g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='=';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9';
+ g_keycodeCharUnshifted[ kVK_Space ]=' ';
+
+ g_keycodeCharShifted[ kVK_ANSI_A ]='A';
+ g_keycodeCharShifted[ kVK_ANSI_S ]='S';
+ g_keycodeCharShifted[ kVK_ANSI_D ]='D';
+ g_keycodeCharShifted[ kVK_ANSI_F ]='F';
+ g_keycodeCharShifted[ kVK_ANSI_H ]='H';
+ g_keycodeCharShifted[ kVK_ANSI_G ]='G';
+ g_keycodeCharShifted[ kVK_ANSI_Z ]='Z';
+ g_keycodeCharShifted[ kVK_ANSI_X ]='X';
+ g_keycodeCharShifted[ kVK_ANSI_C ]='C';
+ g_keycodeCharShifted[ kVK_ANSI_V ]='V';
+ g_keycodeCharShifted[ kVK_ANSI_B ]='B';
+ g_keycodeCharShifted[ kVK_ANSI_Q ]='Q';
+ g_keycodeCharShifted[ kVK_ANSI_W ]='W';
+ g_keycodeCharShifted[ kVK_ANSI_E ]='E';
+ g_keycodeCharShifted[ kVK_ANSI_R ]='R';
+ g_keycodeCharShifted[ kVK_ANSI_Y ]='Y';
+ g_keycodeCharShifted[ kVK_ANSI_T ]='T';
+ g_keycodeCharShifted[ kVK_ANSI_1 ]='!';
+ g_keycodeCharShifted[ kVK_ANSI_2 ]='@';
+ g_keycodeCharShifted[ kVK_ANSI_3 ]='#';
+ g_keycodeCharShifted[ kVK_ANSI_4 ]='$';
+ g_keycodeCharShifted[ kVK_ANSI_6 ]='^';
+ g_keycodeCharShifted[ kVK_ANSI_5 ]='%';
+ g_keycodeCharShifted[ kVK_ANSI_Equal ]='+';
+ g_keycodeCharShifted[ kVK_ANSI_9 ]='(';
+ g_keycodeCharShifted[ kVK_ANSI_7 ]='&';
+ g_keycodeCharShifted[ kVK_ANSI_Minus ]='_';
+ g_keycodeCharShifted[ kVK_ANSI_8 ]='*';
+ g_keycodeCharShifted[ kVK_ANSI_0 ]=')';
+ g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}';
+ g_keycodeCharShifted[ kVK_ANSI_O ]='O';
+ g_keycodeCharShifted[ kVK_ANSI_U ]='U';
+ g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{';
+ g_keycodeCharShifted[ kVK_ANSI_I ]='I';
+ g_keycodeCharShifted[ kVK_ANSI_P ]='P';
+ g_keycodeCharShifted[ kVK_ANSI_L ]='L';
+ g_keycodeCharShifted[ kVK_ANSI_J ]='J';
+ g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"';
+ g_keycodeCharShifted[ kVK_ANSI_K ]='K';
+ g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':';
+ g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|';
+ g_keycodeCharShifted[ kVK_ANSI_Comma ]='<';
+ g_keycodeCharShifted[ kVK_ANSI_Slash ]='?';
+ g_keycodeCharShifted[ kVK_ANSI_N ]='N';
+ g_keycodeCharShifted[ kVK_ANSI_M ]='M';
+ g_keycodeCharShifted[ kVK_ANSI_Period ]='>';
+ g_keycodeCharShifted[ kVK_ANSI_Grave ]='~';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='=';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9';
+ g_keycodeCharShifted[ kVK_Space ]=' ';
+}
+
+- (void)setupImGuiHooks
+{
+ ImGuiIO &io = ImGui::GetIO();
+
+ [self setupKeymaps];
+
+ // Account for retina display for glScissor
+ g_displayScale = [[UIScreen mainScreen] scale];
+
+ ImGuiStyle &style = ImGui::GetStyle();
+ style.TouchExtraPadding = ImVec2( 4.0, 4.0 );
+
+ io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists;
+
+ UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ];
+ [self.view addGestureRecognizer:panRecognizer];
+
+ UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)];
+ [self.view addGestureRecognizer:tapRecoginzer];
+
+ // Fill out the Synergy key map
+ // (for some reason synergy scan codes are off by 1)
+ io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1;
+ io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1;
+ io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1;
+ io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1;
+ io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1;
+ io.KeyMap[ImGuiKey_Home] = kVK_Home+1;
+ io.KeyMap[ImGuiKey_End] = kVK_End+1;
+ io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1;
+ io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1;
+ io.KeyMap[ImGuiKey_Enter] = kVK_Return+1;
+ io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1;
+ io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1;
+ io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1;
+ io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1;
+ io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1;
+ io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1;
+ io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1;
+}
+
+- (void)connectServer: (NSString*)serverName
+{
+ self.serverName = serverName;
+ g_serverName = serverName;
+
+ // Init synergy
+ NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey];
+
+ uSynergyInit( &_synergyCtx );
+ _synergyCtx.m_clientName = strdup( [bundleName UTF8String] );
+ _synergyCtx.m_clientWidth = self.view.bounds.size.width;
+ _synergyCtx.m_clientHeight = self.view.bounds.size.height;
+
+ _synergyCtx.m_connectFunc = ImGui_ConnectFunc;
+ _synergyCtx.m_sendFunc = ImGui_SendFunc;
+ _synergyCtx.m_receiveFunc = ImGui_RecvFunc;
+ _synergyCtx.m_sleepFunc = ImGui_SleepFunc;
+ _synergyCtx.m_traceFunc = ImGui_TraceFunc;
+ _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc;
+
+ _synergyCtx.m_traceFunc = ImGui_TraceFunc;
+ _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback;
+ _synergyCtx.m_mouseCallback = ImGui_MouseCallback;
+ _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback;
+
+ _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx;
+
+ // Create a background thread for synergy
+ _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL );
+ dispatch_async( _synergyQueue, ^{
+ while (1) {
+ uSynergyUpdate( &_synergyCtx );
+ }
+ });
+}
+
+
+- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer
+{
+
+ if ((recognizer.state == UIGestureRecognizerStateBegan) ||
+ (recognizer.state == UIGestureRecognizerStateChanged))
+ {
+ _mouseDown = YES;
+ _touchPos = [recognizer locationInView:self.view];
+ }
+ else
+ {
+ _mouseDown = NO;
+ _touchPos = CGPointMake( -1, -1 );
+ }
+}
+
+- (void)viewDidTap: (UITapGestureRecognizer*)recognizer
+{
+ _touchPos = [recognizer locationInView:self.view];
+ _mouseTapped = YES;
+}
+
+- (void)render
+{
+ ImGui::Render();
+}
+
+- (void)newFrame
+{
+ ImGuiIO& io = ImGui::GetIO();
+ ImGuiStyle &style = ImGui::GetStyle();
+
+ if (!g_FontTexture)
+ {
+ ImGui_ImplIOS_CreateDeviceObjects();
+ }
+
+ io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height );
+
+ io.MouseDrawCursor = g_synergyPtrActive;
+ if (g_synergyPtrActive)
+ {
+ style.TouchExtraPadding = ImVec2( 0.0, 0.0 );
+ io.MousePos = ImVec2( g_mousePosX, g_mousePosY );
+ for (int i=0; i < 3; i++)
+ {
+ io.MouseDown[i] = g_MousePressed[i];
+ }
+
+ // This is an arbitrary scaling factor that works for me. Not sure what units these
+ // mousewheel values from synergy are supposed to be in
+ io.MouseWheel = g_mouseWheelY / 500.0;
+ }
+ else
+ {
+ // Synergy not active, use touch events
+ style.TouchExtraPadding = ImVec2( 4.0, 4.0 );
+ io.MousePos = ImVec2(_touchPos.x, _touchPos.y );
+ if ((_mouseDown) || (_mouseTapped))
+ {
+ io.MouseDown[0] = true;
+ _mouseTapped = NO;
+ }
+ else
+ {
+ io.MouseDown[0] = false;
+ }
+ }
+
+ ImGui::NewFrame();
+}
+@end
+
+// 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)
+// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES
+static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data)
+{
+ // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled
+ GLint last_program, last_texture;
+ glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+ glEnable(GL_BLEND);
+ glBlendEquation(GL_FUNC_ADD);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_SCISSOR_TEST);
+ glActiveTexture(GL_TEXTURE0);
+
+ // Setup orthographic projection matrix
+ const float width = ImGui::GetIO().DisplaySize.x;
+ const float height = ImGui::GetIO().DisplaySize.y;
+ const float ortho_projection[4][4] =
+ {
+ { 2.0f/width, 0.0f, 0.0f, 0.0f },
+ { 0.0f, 2.0f/-height, 0.0f, 0.0f },
+ { 0.0f, 0.0f, -1.0f, 0.0f },
+ { -1.0f, 1.0f, 0.0f, 1.0f },
+ };
+ glUseProgram(g_ShaderHandle);
+ glUniform1i(g_AttribLocationTex, 0);
+ glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
+ glBindVertexArray(g_VaoHandle);
+
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
+ {
+ ImDrawList* cmd_list = draw_data->CmdLists[n];
+ ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front();
+
+ glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
+ const int needed_vtx_size = cmd_list->VtxBuffer.Size * sizeof(ImDrawVert);
+ if (g_VboSize < needed_vtx_size)
+ {
+ // Grow our buffer if needed
+ g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert);
+ glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW);
+ }
+
+ unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
+ if (!vtx_data)
+ continue;
+ memcpy(vtx_data, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
+ {
+ const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
+ if (pcmd->UserCallback)
+ {
+ pcmd->UserCallback(cmd_list, pcmd);
+ }
+ else
+ {
+ glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId);
+ glScissor((int)(pcmd->ClipRect.x * g_displayScale),
+ (int)((height - pcmd->ClipRect.w) * g_displayScale),
+ (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale),
+ (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale));
+ glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer );
+ }
+ idx_buffer += pcmd->ElemCount;
+ }
+ }
+
+ // Restore modified state
+ glBindVertexArray(0);
+ glBindBuffer( GL_ARRAY_BUFFER, 0);
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_DEPTH_TEST);
+ glUseProgram(last_program);
+ glDisable(GL_SCISSOR_TEST);
+ glBindTexture(GL_TEXTURE_2D, last_texture);
+}
+
+void ImGui_ImplIOS_CreateFontsTexture()
+{
+ // Build texture atlas
+ ImGuiIO& io = ImGui::GetIO();
+ unsigned char* pixels;
+ int width, height;
+ io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader.
+
+ // Upload texture to graphics system
+ GLint last_texture;
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+ glGenTextures(1, &g_FontTexture);
+ glBindTexture(GL_TEXTURE_2D, g_FontTexture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+
+ // Store our identifier
+ io.Fonts->TexID = (void *)(intptr_t)g_FontTexture;
+
+ // Restore state
+ glBindTexture(GL_TEXTURE_2D, last_texture);
+}
+
+bool ImGui_ImplIOS_CreateDeviceObjects()
+{
+ const GLchar *vertex_shader =
+ "uniform mat4 ProjMtx;\n"
+ "attribute highp vec2 Position;\n"
+ "attribute highp vec2 UV;\n"
+ "attribute highp vec4 Color;\n"
+ "varying vec2 Frag_UV;\n"
+ "varying vec4 Frag_Color;\n"
+ "void main()\n"
+ "{\n"
+ " Frag_UV = UV;\n"
+ " Frag_Color = Color;\n"
+ " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
+ "}\n";
+
+ const GLchar* fragment_shader =
+ "uniform sampler2D Texture;\n"
+ "varying highp vec2 Frag_UV;\n"
+ "varying highp vec4 Frag_Color;\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n"
+ "}\n";
+
+ g_ShaderHandle = glCreateProgram();
+ g_VertHandle = glCreateShader(GL_VERTEX_SHADER);
+ g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER);
+ glShaderSource(g_VertHandle, 1, &vertex_shader, 0);
+ glShaderSource(g_FragHandle, 1, &fragment_shader, 0);
+ glCompileShader(g_VertHandle);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log);
+ NSLog(@"VERTEX Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glCompileShader(g_FragHandle);
+
+#if defined(DEBUG)
+ glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log);
+ NSLog(@"FRAGMENT Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glAttachShader(g_ShaderHandle, g_VertHandle);
+ glAttachShader(g_ShaderHandle, g_FragHandle);
+ glLinkProgram(g_ShaderHandle);
+
+ g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture");
+ g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx");
+ g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position");
+ g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV");
+ g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color");
+
+ glGenBuffers(1, &g_VboHandle);
+
+ glGenVertexArrays(1, &g_VaoHandle);
+ glBindVertexArray(g_VaoHandle);
+ glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
+ glEnableVertexAttribArray(g_AttribLocationPosition);
+ glEnableVertexAttribArray(g_AttribLocationUV);
+ glEnableVertexAttribArray(g_AttribLocationColor);
+
+#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
+ glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos));
+ glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv));
+ glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col));
+#undef OFFSETOF
+ glBindVertexArray(0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ ImGui_ImplIOS_CreateFontsTexture();
+
+ return true;
+}
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore
new file mode 100644
index 0000000..8feda89
--- /dev/null
+++ b/examples/apple_example/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+imguiex.xcodeproj/project.xcworkspace/
+imguiex.xcodeproj/xcuserdata/
\ No newline at end of file
diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md
new file mode 100644
index 0000000..339f6bf
--- /dev/null
+++ b/examples/apple_example/README.md
@@ -0,0 +1,41 @@
+# iOS / OSX example
+
+## Introduction
+
+This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device.
+
+It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy.
+
+Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active.
+
+## How to Use on iOS
+
+* In Synergy, go to Preferences, and uncheck "Use SSL encryption"
+* Run the example app.
+* Tap the "servername" button in the corner
+* Enter the name or the IP of your synergy host
+* If you had previously connected to a server, you may need to kill and re-start the app.
+
+## How to Build on OSX
+
+* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh)
+* Run the command: `brew install glfw3`
+* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme
+* Click `Run` button
+
+## Notes and TODOs
+
+Things that would be nice but I didn't get around to doing:
+
+* iOS software keyboard not supported for text inputs
+* iOS hardware (bluetooth) keyboards not supported
+* Graceful disconnect/reconnect from uSynergy.
+* Copy/Paste not well-supported
+
+## C++ on iOS / OSX
+
+ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension.
+
+Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer.
+
+In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly.
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h
new file mode 100644
index 0000000..82f1542
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.h
@@ -0,0 +1,13 @@
+//
+// AppDelegate.h
+// imguiex
+
+#import
+
+@interface AppDelegate : UIResponder
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m
new file mode 100644
index 0000000..ab83101
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.m
@@ -0,0 +1,41 @@
+//
+// AppDelegate.m
+// imguiex
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Override point for customization after application launch.
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
new file mode 100644
index 0000000..5717c00
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..90dfb2e
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h
new file mode 100644
index 0000000..3323cfd
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.h
@@ -0,0 +1,12 @@
+//
+// GameViewController.h
+// imguiex
+
+// This is the OpenGL Example template from XCode, modified to support ImGui
+
+#import
+#import
+
+@interface GameViewController : GLKViewController
+
+@end
diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m
new file mode 100644
index 0000000..e902f7a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.m
@@ -0,0 +1,481 @@
+//
+// GameViewController.m
+// imguiex
+//
+#import "GameViewController.h"
+#import
+
+#import "imgui_impl_ios.h"
+#import "debug_hud.h"
+
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
+
+#define SERVERNAME_KEY @"ServerName"
+
+#define SERVERNAME_ALERT_TAG (10)
+
+// Uniform index.
+enum
+{
+ UNIFORM_MODELVIEWPROJECTION_MATRIX,
+ UNIFORM_NORMAL_MATRIX,
+ UNIFORM_DIFFUSE_COLOR,
+
+ NUM_UNIFORMS
+};
+GLint uniforms[NUM_UNIFORMS];
+
+// Attribute index.
+enum
+{
+ ATTRIB_VERTEX,
+ ATTRIB_NORMAL,
+ NUM_ATTRIBUTES
+};
+
+GLfloat gCubeVertexData[216] =
+{
+ // Data layout for each line below is:
+ // positionX, positionY, positionZ, normalX, normalY, normalZ,
+ 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+
+ 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+
+ -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+
+ -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+
+ 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+
+ 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f
+};
+
+@interface GameViewController ()
+{
+ GLuint _program;
+
+ GLKMatrix4 _modelViewProjectionMatrix;
+ GLKMatrix3 _normalMatrix;
+ float _rotation;
+
+ GLuint _vertexArray;
+ GLuint _vertexBuffer;
+
+ DebugHUD _hud;
+}
+@property (strong, nonatomic) EAGLContext *context;
+@property (strong, nonatomic) GLKBaseEffect *effect;
+@property (strong, nonatomic) ImGuiHelper *imgui;
+@property (weak, nonatomic) IBOutlet UIButton *btnServername;
+
+@property (strong, nonatomic) NSString *serverName;
+
+- (IBAction)onServernameTapped:(id)sender;
+
+- (void)setupGL;
+- (void)tearDownGL;
+
+- (BOOL)loadShaders;
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file;
+- (BOOL)linkProgram:(GLuint)prog;
+- (BOOL)validateProgram:(GLuint)prog;
+@end
+
+@implementation GameViewController
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+
+ if (!self.context) {
+ NSLog(@"Failed to create ES context");
+ }
+
+ GLKView *view = (GLKView *)self.view;
+ view.context = self.context;
+ view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
+
+ [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
+
+ [self setupGL];
+
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ];
+ self.imgui = [[ImGuiHelper alloc] initWithView:self.view ];
+ if (self.serverName)
+ {
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+ [self.imgui connectServer: self.serverName ];
+ }
+
+ DebugHUD_InitDefaults( &_hud );
+}
+
+- (void)dealloc
+{
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+
+ if ([self isViewLoaded] && ([[self view] window] == nil)) {
+ self.view = nil;
+
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+ self.context = nil;
+ }
+
+ // Dispose of any resources that can be recreated.
+}
+
+
+- (BOOL)prefersStatusBarHidden {
+ return YES;
+}
+
+- (IBAction)onServernameTapped:(id)sender
+{
+ UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ];
+ alert.alertViewStyle = UIAlertViewStylePlainTextInput;
+ alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to
+ [alert show];
+}
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG))
+ {
+ // This is really janky. I usually just hardcode the servername since I'm building it anyway.
+ // If you want to properly handle updating the server, you'll want to tear down and recreate
+ // the usynergy stuff in connectServer
+ BOOL serverNameWasSet = self.serverName.length > 0;
+ NSString *serverName = [[alertView textFieldAtIndex:0] text];
+
+ if ([serverName length] > 0) {
+ self.serverName = serverName;
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ [userDefaults setObject:serverName forKey:SERVERNAME_KEY ];
+ [userDefaults synchronize];
+
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+
+ // If we hadn't previously connected, try now
+ if (!serverNameWasSet) {
+ [self.imgui connectServer:self.serverName];
+ }
+ else
+ {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated"
+ message:@"Restart the app to connect the server"
+ delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
+ [alert show];
+ }
+ }
+ }
+}
+
+- (void)setupGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ [self loadShaders];
+
+ self.effect = [[GLKBaseEffect alloc] init];
+ self.effect.light0.enabled = GL_TRUE;
+ self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f);
+
+ glEnable(GL_DEPTH_TEST);
+
+ glGenVertexArraysOES(1, &_vertexArray);
+ glBindVertexArrayOES(_vertexArray);
+
+ glGenBuffers(1, &_vertexBuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);
+
+ glEnableVertexAttribArray(GLKVertexAttribPosition);
+ glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
+ glEnableVertexAttribArray(GLKVertexAttribNormal);
+ glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
+
+ glBindVertexArrayOES(0);
+
+
+}
+
+- (void)tearDownGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ glDeleteBuffers(1, &_vertexBuffer);
+ glDeleteVertexArraysOES(1, &_vertexArray);
+
+ self.effect = nil;
+
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+}
+
+#pragma mark - GLKView and GLKViewController delegate methods
+
+- (void)update
+{
+ float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height);
+ GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
+
+ self.effect.transform.projectionMatrix = projectionMatrix;
+
+ GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);
+ baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
+
+ // Compute the model view matrix for the object rendered with GLKit
+ GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ self.effect.transform.modelviewMatrix = modelViewMatrix;
+
+ // Compute the model view matrix for the object rendered with ES2
+ modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
+
+ _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
+
+ _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0));
+}
+
+
+- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
+{
+ glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glBindVertexArrayOES(_vertexArray);
+
+ // Render the object with GLKit
+ [self.effect prepareToDraw];
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ // Render the object again with ES2
+ glUseProgram(_program);
+
+ glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
+ glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
+ glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] );
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ [self.imgui newFrame];
+
+ // Now do our ImGUI UI
+ DebugHUD_DoInterface( &_hud );
+
+ self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f);
+
+ // Now render Imgui
+ [self.imgui render];
+
+}
+
+#pragma mark - OpenGL ES 2 shader compilation
+
+- (BOOL)loadShaders
+{
+ GLuint vertShader, fragShader;
+ NSString *vertShaderPathname, *fragShaderPathname;
+
+ // Create shader program.
+ _program = glCreateProgram();
+
+ // Create and compile vertex shader.
+ vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
+ if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
+ NSLog(@"Failed to compile vertex shader");
+ return NO;
+ }
+
+ // Create and compile fragment shader.
+ fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
+ if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
+ NSLog(@"Failed to compile fragment shader");
+ return NO;
+ }
+
+ // Attach vertex shader to program.
+ glAttachShader(_program, vertShader);
+
+ // Attach fragment shader to program.
+ glAttachShader(_program, fragShader);
+
+ // Bind attribute locations.
+ // This needs to be done prior to linking.
+ glBindAttribLocation(_program, GLKVertexAttribPosition, "position");
+ glBindAttribLocation(_program, GLKVertexAttribNormal, "normal");
+
+ // Link program.
+ if (![self linkProgram:_program]) {
+ NSLog(@"Failed to link program: %d", _program);
+
+ if (vertShader) {
+ glDeleteShader(vertShader);
+ vertShader = 0;
+ }
+ if (fragShader) {
+ glDeleteShader(fragShader);
+ fragShader = 0;
+ }
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+
+ return NO;
+ }
+
+ // Get uniform locations.
+ uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix");
+ uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix");
+ uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor");
+
+ // Release vertex and fragment shaders.
+ if (vertShader) {
+ glDetachShader(_program, vertShader);
+ glDeleteShader(vertShader);
+ }
+ if (fragShader) {
+ glDetachShader(_program, fragShader);
+ glDeleteShader(fragShader);
+ }
+
+ return YES;
+}
+
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
+{
+ GLint status;
+ const GLchar *source;
+
+ source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
+ if (!source) {
+ NSLog(@"Failed to load vertex shader");
+ return NO;
+ }
+
+ *shader = glCreateShader(type);
+ glShaderSource(*shader, 1, &source, NULL);
+ glCompileShader(*shader);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(*shader, logLength, &logLength, log);
+ NSLog(@"Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
+ if (status == 0) {
+ glDeleteShader(*shader);
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)linkProgram:(GLuint)prog
+{
+ GLint status;
+ glLinkProgram(prog);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program link log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetProgramiv(prog, GL_LINK_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)validateProgram:(GLuint)prog
+{
+ GLint logLength, status;
+
+ glValidateProgram(prog);
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program validate log:\n%s", log);
+ free(log);
+ }
+
+ glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..06b60d8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,77 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@2x~iphone.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@3x~iphone.png",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76~ipad.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76@2x~ipad.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "83.5x83.5",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
new file mode 100644
index 0000000..d728bc3
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
new file mode 100644
index 0000000..f48b799
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
new file mode 100644
index 0000000..67b08b8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
new file mode 100644
index 0000000..ae88e04
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist
new file mode 100644
index 0000000..bc6f548
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Info.plist
@@ -0,0 +1,49 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ org.imgui.example.$(PRODUCT_NAME:rfc1034identifier)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UIStatusBarHidden
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh
new file mode 100644
index 0000000..4000524
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh
@@ -0,0 +1,10 @@
+//
+// Shader.fsh
+// imguiex
+
+varying lowp vec4 colorVarying;
+
+void main()
+{
+ gl_FragColor = colorVarying;
+}
diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh
new file mode 100644
index 0000000..313c3d7
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh
@@ -0,0 +1,25 @@
+//
+// Shader.vsh
+// imguiex
+
+attribute vec4 position;
+attribute vec3 normal;
+
+varying lowp vec4 colorVarying;
+
+uniform vec3 diffuseColor;
+uniform mat4 modelViewProjectionMatrix;
+uniform mat3 normalMatrix;
+
+void main()
+{
+ vec3 eyeNormal = normalize(normalMatrix * normal);
+ vec3 lightPosition = vec3(0.0, 0.0, 1.0);
+
+ float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition)));
+
+ vec3 colorLit = diffuseColor * nDotVP;
+ colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 );
+
+ gl_Position = modelViewProjectionMatrix * position;
+}
diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp
new file mode 100644
index 0000000..c75938a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/debug_hud.cpp
@@ -0,0 +1,45 @@
+//
+// debug_hud.cpp
+// imguiex
+
+#include
+
+#include "debug_hud.h"
+#include "imgui.h"
+
+void DebugHUD_InitDefaults( DebugHUD *hud )
+{
+ hud->show_test_window = true;
+ hud->show_example_window = true;
+ hud->rotation_speed = 15.0f;
+
+ hud->cubeColor1[0] = 0.4f;
+ hud->cubeColor1[1] = 0.4f;
+ hud->cubeColor1[2] = 1.0f;
+ hud->cubeColor1[3] = 1.0f;
+
+ hud->cubeColor2[0] = 1.0f;
+ hud->cubeColor2[1] = 0.4f;
+ hud->cubeColor2[2] = 0.4f;
+ hud->cubeColor2[3] = 1.0f;
+}
+
+void DebugHUD_DoInterface( DebugHUD *hud )
+{
+ if (hud->show_test_window)
+ {
+ ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver );
+ ImGui::ShowTestWindow( &hud->show_test_window );
+ }
+
+ if (hud->show_example_window)
+ {
+ ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver );
+ ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver );
+ ImGui::Begin("Another Window", &hud->show_example_window);
+ ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1);
+ ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2);
+ ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f);
+ ImGui::End();
+ }
+}
diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h
new file mode 100644
index 0000000..17122f5
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/debug_hud.h
@@ -0,0 +1,25 @@
+//
+// debug_hud.h
+// imguiex
+
+#pragma once
+
+typedef struct DebugHUD
+{
+ bool show_test_window;
+ bool show_example_window;
+ float rotation_speed;
+ float cubeColor1[4];
+ float cubeColor2[4];
+} DebugHUD;
+
+#if __cplusplus
+extern "C" {
+#endif
+
+void DebugHUD_InitDefaults( DebugHUD *hud );
+void DebugHUD_DoInterface( DebugHUD *hud );
+
+#if __cplusplus
+}
+#endif
diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png
new file mode 100644
index 0000000..820e4d7
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h
new file mode 100644
index 0000000..9b01dd3
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h
@@ -0,0 +1,22 @@
+// ImGui iOS+OpenGL+Synergy binding
+// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much.
+// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application.
+
+// by Joel Davis (joeld42@gmail.com)
+
+#pragma once
+
+#include
+#include
+
+@interface ImGuiHelper : NSObject
+
+- (id) initWithView: (UIView *)view;
+
+- (void)connectServer: (NSString*)serverName;
+
+- (void)render;
+- (void)newFrame;
+
+@end
diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm
new file mode 100644
index 0000000..893dbf9
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm
@@ -0,0 +1,806 @@
+// ImGui iOS+OpenGL+Synergy binding
+// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much.
+// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application.
+
+// TODO:
+// - Clipboard is not supported.
+
+#import
+#import
+
+#include
+#include
+#include
+#include
+
+#include "imgui_impl_ios.h"
+#include "imgui.h"
+
+#include "uSynergy.h"
+
+// From Carbon HIToolbox/Events.h
+// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247
+enum {
+ kVK_ANSI_A = 0x00,
+ kVK_ANSI_S = 0x01,
+ kVK_ANSI_D = 0x02,
+ kVK_ANSI_F = 0x03,
+ kVK_ANSI_H = 0x04,
+ kVK_ANSI_G = 0x05,
+ kVK_ANSI_Z = 0x06,
+ kVK_ANSI_X = 0x07,
+ kVK_ANSI_C = 0x08,
+ kVK_ANSI_V = 0x09,
+ kVK_ANSI_B = 0x0B,
+ kVK_ANSI_Q = 0x0C,
+ kVK_ANSI_W = 0x0D,
+ kVK_ANSI_E = 0x0E,
+ kVK_ANSI_R = 0x0F,
+ kVK_ANSI_Y = 0x10,
+ kVK_ANSI_T = 0x11,
+ kVK_ANSI_1 = 0x12,
+ kVK_ANSI_2 = 0x13,
+ kVK_ANSI_3 = 0x14,
+ kVK_ANSI_4 = 0x15,
+ kVK_ANSI_6 = 0x16,
+ kVK_ANSI_5 = 0x17,
+ kVK_ANSI_Equal = 0x18,
+ kVK_ANSI_9 = 0x19,
+ kVK_ANSI_7 = 0x1A,
+ kVK_ANSI_Minus = 0x1B,
+ kVK_ANSI_8 = 0x1C,
+ kVK_ANSI_0 = 0x1D,
+ kVK_ANSI_RightBracket = 0x1E,
+ kVK_ANSI_O = 0x1F,
+ kVK_ANSI_U = 0x20,
+ kVK_ANSI_LeftBracket = 0x21,
+ kVK_ANSI_I = 0x22,
+ kVK_ANSI_P = 0x23,
+ kVK_ANSI_L = 0x25,
+ kVK_ANSI_J = 0x26,
+ kVK_ANSI_Quote = 0x27,
+ kVK_ANSI_K = 0x28,
+ kVK_ANSI_Semicolon = 0x29,
+ kVK_ANSI_Backslash = 0x2A,
+ kVK_ANSI_Comma = 0x2B,
+ kVK_ANSI_Slash = 0x2C,
+ kVK_ANSI_N = 0x2D,
+ kVK_ANSI_M = 0x2E,
+ kVK_ANSI_Period = 0x2F,
+ kVK_ANSI_Grave = 0x32,
+ kVK_ANSI_KeypadDecimal = 0x41,
+ kVK_ANSI_KeypadMultiply = 0x43,
+ kVK_ANSI_KeypadPlus = 0x45,
+ kVK_ANSI_KeypadClear = 0x47,
+ kVK_ANSI_KeypadDivide = 0x4B,
+ kVK_ANSI_KeypadEnter = 0x4C,
+ kVK_ANSI_KeypadMinus = 0x4E,
+ kVK_ANSI_KeypadEquals = 0x51,
+ kVK_ANSI_Keypad0 = 0x52,
+ kVK_ANSI_Keypad1 = 0x53,
+ kVK_ANSI_Keypad2 = 0x54,
+ kVK_ANSI_Keypad3 = 0x55,
+ kVK_ANSI_Keypad4 = 0x56,
+ kVK_ANSI_Keypad5 = 0x57,
+ kVK_ANSI_Keypad6 = 0x58,
+ kVK_ANSI_Keypad7 = 0x59,
+ kVK_ANSI_Keypad8 = 0x5B,
+ kVK_ANSI_Keypad9 = 0x5C
+};
+
+/* keycodes for keys that are independent of keyboard layout*/
+enum {
+ kVK_Return = 0x24,
+ kVK_Tab = 0x30,
+ kVK_Space = 0x31,
+ kVK_Delete = 0x33,
+ kVK_Escape = 0x35,
+ kVK_Command = 0x37,
+ kVK_Shift = 0x38,
+ kVK_CapsLock = 0x39,
+ kVK_Option = 0x3A,
+ kVK_Control = 0x3B,
+ kVK_RightShift = 0x3C,
+ kVK_RightOption = 0x3D,
+ kVK_RightControl = 0x3E,
+ kVK_Function = 0x3F,
+ kVK_F17 = 0x40,
+ kVK_VolumeUp = 0x48,
+ kVK_VolumeDown = 0x49,
+ kVK_Mute = 0x4A,
+ kVK_F18 = 0x4F,
+ kVK_F19 = 0x50,
+ kVK_F20 = 0x5A,
+ kVK_F5 = 0x60,
+ kVK_F6 = 0x61,
+ kVK_F7 = 0x62,
+ kVK_F3 = 0x63,
+ kVK_F8 = 0x64,
+ kVK_F9 = 0x65,
+ kVK_F11 = 0x67,
+ kVK_F13 = 0x69,
+ kVK_F16 = 0x6A,
+ kVK_F14 = 0x6B,
+ kVK_F10 = 0x6D,
+ kVK_F12 = 0x6F,
+ kVK_F15 = 0x71,
+ kVK_Help = 0x72,
+ kVK_Home = 0x73,
+ kVK_PageUp = 0x74,
+ kVK_ForwardDelete = 0x75,
+ kVK_F4 = 0x76,
+ kVK_End = 0x77,
+ kVK_F2 = 0x78,
+ kVK_PageDown = 0x79,
+ kVK_F1 = 0x7A,
+ kVK_LeftArrow = 0x7B,
+ kVK_RightArrow = 0x7C,
+ kVK_DownArrow = 0x7D,
+ kVK_UpArrow = 0x7E
+};
+
+static char g_keycodeCharUnshifted[256] = {};
+static char g_keycodeCharShifted[256] = {};
+
+//static double g_Time = 0.0f;
+static bool g_MousePressed[3] = { false, false, false };
+static float g_mouseWheelX = 0.0f;
+static float g_mouseWheelY = 0.0f;
+
+static GLuint g_FontTexture = 0;
+static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0;
+static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0;
+static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0;
+static size_t g_VboSize = 0;
+static unsigned int g_VboHandle = 0, g_VaoHandle = 0;
+static float g_displayScale;
+
+static int usynergy_sockfd;
+static bool g_synergyPtrActive = false;
+static uint16_t g_mousePosX = 0;
+static uint16_t g_mousePosY = 0;
+
+static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data);
+bool ImGui_ImplIOS_CreateDeviceObjects();
+
+static NSString *g_serverName;
+
+uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie)
+{
+ // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since
+ // uSynergy does not support SSL.
+
+ NSLog( @"Connect Func!");
+ struct addrinfo hints, *res;
+
+ // first, load up address structs with getaddrinfo():
+ memset(&hints, 0, sizeof hints);
+ hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
+ hints.ai_socktype = SOCK_STREAM;
+
+ // get server address
+ getaddrinfo([g_serverName UTF8String], "24800", &hints, &res);
+
+ if (!res)
+ {
+ NSLog( @"Could not find server: %@", g_serverName );
+ return USYNERGY_FALSE;
+ }
+
+ // make a socket:
+ usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+
+ // connect it to the address and port we passed in to getaddrinfo():
+ int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen);
+ if (!ret) {
+ NSLog( @"Connect succeeded...");
+ } else {
+ NSLog( @"Connect failed, %d", ret );
+ }
+
+
+ return USYNERGY_TRUE;
+}
+
+uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length)
+{
+// NSLog( @"Send Func" );
+ send( usynergy_sockfd, buffer, length, 0 );
+
+ return USYNERGY_TRUE;
+}
+
+uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength)
+{
+ *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 );
+
+ return USYNERGY_TRUE;
+}
+
+void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs)
+{
+ usleep( timeMs * 1000 );
+}
+
+uint32_t ImGui_GetTimeFunc()
+{
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+
+ return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000);
+}
+
+void ImGui_TraceFunc(uSynergyCookie cookie, const char *text)
+{
+ puts(text);
+}
+
+void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active)
+{
+ g_synergyPtrActive = active;
+// printf( "Synergy: screen activate %s\n", active?"YES":"NO" );
+}
+
+void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY,
+ uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle)
+{
+// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY );
+ uSynergyContext *ctx = (uSynergyContext*)cookie;
+ g_mousePosX = x;
+ g_mousePosY = y;
+ g_mouseWheelX = wheelX;
+ g_mouseWheelY = wheelY;
+ g_MousePressed[0] = buttonLeft;
+ g_MousePressed[1] = buttonMiddle;
+ g_MousePressed[2] = buttonRight;
+
+ ctx->m_mouseWheelX = 0;
+ ctx->m_mouseWheelY = 0;
+}
+
+void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key,
+ uint16_t modifiers, uSynergyBool down, uSynergyBool repeat)
+{
+ int scanCode = key-1;
+// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false");
+ ImGuiIO& io = ImGui::GetIO();
+ io.KeysDown[key] = down;
+ io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT);
+ io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL);
+ io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT);
+ io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN);
+
+ // Add this as keyboard input
+ if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL))
+ {
+ // If this key maps to a character input, apply it
+ int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode];
+ io.AddInputCharacter((unsigned short)charForKeycode);
+ }
+
+}
+
+void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY)
+{
+ printf("Synergy: joystick callback TODO\n");
+}
+
+void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size)
+{
+ printf("Synergy: clipboard callback TODO\n" );
+}
+
+@interface ImGuiHelper ()
+{
+ BOOL _mouseDown;
+ BOOL _mouseTapped;
+ CGPoint _touchPos;
+
+ uSynergyContext _synergyCtx;
+ dispatch_queue_t _synergyQueue;
+}
+@property (nonatomic, weak) UIView *view;
+@property (nonatomic, strong) NSString *serverName;
+
+@end
+
+@implementation ImGuiHelper
+
+- (id) initWithView: (UIView *)view
+{
+ self = [super init];
+ if (self)
+ {
+ self.view = view;
+
+ [self setupImGuiHooks];
+ }
+ return self;
+}
+
+- (void)setupKeymaps
+{
+ // The keyboard mapping is a big headache. I tried for a while to find a better way to do this,
+ // but this was the best I could come up with. There are some device independent API's available
+ // to convert scan codes to unicode characters, but these are only available on mac and not
+ // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do
+ // this or any way to get the character codes out of usynergy.
+ g_keycodeCharUnshifted[ kVK_ANSI_A ]='a';
+ g_keycodeCharUnshifted[ kVK_ANSI_S ]='s';
+ g_keycodeCharUnshifted[ kVK_ANSI_D ]='d';
+ g_keycodeCharUnshifted[ kVK_ANSI_F ]='f';
+ g_keycodeCharUnshifted[ kVK_ANSI_H ]='h';
+ g_keycodeCharUnshifted[ kVK_ANSI_G ]='g';
+ g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z';
+ g_keycodeCharUnshifted[ kVK_ANSI_X ]='x';
+ g_keycodeCharUnshifted[ kVK_ANSI_C ]='c';
+ g_keycodeCharUnshifted[ kVK_ANSI_V ]='v';
+ g_keycodeCharUnshifted[ kVK_ANSI_B ]='b';
+ g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q';
+ g_keycodeCharUnshifted[ kVK_ANSI_W ]='w';
+ g_keycodeCharUnshifted[ kVK_ANSI_E ]='e';
+ g_keycodeCharUnshifted[ kVK_ANSI_R ]='r';
+ g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y';
+ g_keycodeCharUnshifted[ kVK_ANSI_T ]='t';
+ g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1';
+ g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2';
+ g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3';
+ g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4';
+ g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6';
+ g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5';
+ g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='=';
+ g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9';
+ g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7';
+ g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-';
+ g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8';
+ g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0';
+ g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']';
+ g_keycodeCharUnshifted[ kVK_ANSI_O ]='o';
+ g_keycodeCharUnshifted[ kVK_ANSI_U ]='u';
+ g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='[';
+ g_keycodeCharUnshifted[ kVK_ANSI_I ]='i';
+ g_keycodeCharUnshifted[ kVK_ANSI_P ]='p';
+ g_keycodeCharUnshifted[ kVK_ANSI_L ]='l';
+ g_keycodeCharUnshifted[ kVK_ANSI_J ]='j';
+ g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\'';
+ g_keycodeCharUnshifted[ kVK_ANSI_K ]='k';
+ g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';';
+ g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\';
+ g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=',';
+ g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/';
+ g_keycodeCharUnshifted[ kVK_ANSI_N ]='n';
+ g_keycodeCharUnshifted[ kVK_ANSI_M ]='m';
+ g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.';
+ g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='=';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9';
+ g_keycodeCharUnshifted[ kVK_Space ]=' ';
+
+ g_keycodeCharShifted[ kVK_ANSI_A ]='A';
+ g_keycodeCharShifted[ kVK_ANSI_S ]='S';
+ g_keycodeCharShifted[ kVK_ANSI_D ]='D';
+ g_keycodeCharShifted[ kVK_ANSI_F ]='F';
+ g_keycodeCharShifted[ kVK_ANSI_H ]='H';
+ g_keycodeCharShifted[ kVK_ANSI_G ]='G';
+ g_keycodeCharShifted[ kVK_ANSI_Z ]='Z';
+ g_keycodeCharShifted[ kVK_ANSI_X ]='X';
+ g_keycodeCharShifted[ kVK_ANSI_C ]='C';
+ g_keycodeCharShifted[ kVK_ANSI_V ]='V';
+ g_keycodeCharShifted[ kVK_ANSI_B ]='B';
+ g_keycodeCharShifted[ kVK_ANSI_Q ]='Q';
+ g_keycodeCharShifted[ kVK_ANSI_W ]='W';
+ g_keycodeCharShifted[ kVK_ANSI_E ]='E';
+ g_keycodeCharShifted[ kVK_ANSI_R ]='R';
+ g_keycodeCharShifted[ kVK_ANSI_Y ]='Y';
+ g_keycodeCharShifted[ kVK_ANSI_T ]='T';
+ g_keycodeCharShifted[ kVK_ANSI_1 ]='!';
+ g_keycodeCharShifted[ kVK_ANSI_2 ]='@';
+ g_keycodeCharShifted[ kVK_ANSI_3 ]='#';
+ g_keycodeCharShifted[ kVK_ANSI_4 ]='$';
+ g_keycodeCharShifted[ kVK_ANSI_6 ]='^';
+ g_keycodeCharShifted[ kVK_ANSI_5 ]='%';
+ g_keycodeCharShifted[ kVK_ANSI_Equal ]='+';
+ g_keycodeCharShifted[ kVK_ANSI_9 ]='(';
+ g_keycodeCharShifted[ kVK_ANSI_7 ]='&';
+ g_keycodeCharShifted[ kVK_ANSI_Minus ]='_';
+ g_keycodeCharShifted[ kVK_ANSI_8 ]='*';
+ g_keycodeCharShifted[ kVK_ANSI_0 ]=')';
+ g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}';
+ g_keycodeCharShifted[ kVK_ANSI_O ]='O';
+ g_keycodeCharShifted[ kVK_ANSI_U ]='U';
+ g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{';
+ g_keycodeCharShifted[ kVK_ANSI_I ]='I';
+ g_keycodeCharShifted[ kVK_ANSI_P ]='P';
+ g_keycodeCharShifted[ kVK_ANSI_L ]='L';
+ g_keycodeCharShifted[ kVK_ANSI_J ]='J';
+ g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"';
+ g_keycodeCharShifted[ kVK_ANSI_K ]='K';
+ g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':';
+ g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|';
+ g_keycodeCharShifted[ kVK_ANSI_Comma ]='<';
+ g_keycodeCharShifted[ kVK_ANSI_Slash ]='?';
+ g_keycodeCharShifted[ kVK_ANSI_N ]='N';
+ g_keycodeCharShifted[ kVK_ANSI_M ]='M';
+ g_keycodeCharShifted[ kVK_ANSI_Period ]='>';
+ g_keycodeCharShifted[ kVK_ANSI_Grave ]='~';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='=';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9';
+ g_keycodeCharShifted[ kVK_Space ]=' ';
+}
+
+- (void)setupImGuiHooks
+{
+ ImGuiIO &io = ImGui::GetIO();
+
+ [self setupKeymaps];
+
+ // Account for retina display for glScissor
+ g_displayScale = [[UIScreen mainScreen] scale];
+
+ ImGuiStyle &style = ImGui::GetStyle();
+ style.TouchExtraPadding = ImVec2( 4.0, 4.0 );
+
+ io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists;
+
+ UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ];
+ [self.view addGestureRecognizer:panRecognizer];
+
+ UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)];
+ [self.view addGestureRecognizer:tapRecoginzer];
+
+ // Fill out the Synergy key map
+ // (for some reason synergy scan codes are off by 1)
+ io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1;
+ io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1;
+ io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1;
+ io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1;
+ io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1;
+ io.KeyMap[ImGuiKey_Home] = kVK_Home+1;
+ io.KeyMap[ImGuiKey_End] = kVK_End+1;
+ io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1;
+ io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1;
+ io.KeyMap[ImGuiKey_Enter] = kVK_Return+1;
+ io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1;
+ io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1;
+ io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1;
+ io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1;
+ io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1;
+ io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1;
+ io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1;
+}
+
+- (void)connectServer: (NSString*)serverName
+{
+ self.serverName = serverName;
+ g_serverName = serverName;
+
+ // Init synergy
+ NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey];
+
+ uSynergyInit( &_synergyCtx );
+ _synergyCtx.m_clientName = strdup( [bundleName UTF8String] );
+ _synergyCtx.m_clientWidth = self.view.bounds.size.width;
+ _synergyCtx.m_clientHeight = self.view.bounds.size.height;
+
+ _synergyCtx.m_connectFunc = ImGui_ConnectFunc;
+ _synergyCtx.m_sendFunc = ImGui_SendFunc;
+ _synergyCtx.m_receiveFunc = ImGui_RecvFunc;
+ _synergyCtx.m_sleepFunc = ImGui_SleepFunc;
+ _synergyCtx.m_traceFunc = ImGui_TraceFunc;
+ _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc;
+
+ _synergyCtx.m_traceFunc = ImGui_TraceFunc;
+ _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback;
+ _synergyCtx.m_mouseCallback = ImGui_MouseCallback;
+ _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback;
+
+ _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx;
+
+ // Create a background thread for synergy
+ _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL );
+ dispatch_async( _synergyQueue, ^{
+ while (1) {
+ uSynergyUpdate( &_synergyCtx );
+ }
+ });
+}
+
+
+- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer
+{
+
+ if ((recognizer.state == UIGestureRecognizerStateBegan) ||
+ (recognizer.state == UIGestureRecognizerStateChanged))
+ {
+ _mouseDown = YES;
+ _touchPos = [recognizer locationInView:self.view];
+ }
+ else
+ {
+ _mouseDown = NO;
+ _touchPos = CGPointMake( -1, -1 );
+ }
+}
+
+- (void)viewDidTap: (UITapGestureRecognizer*)recognizer
+{
+ _touchPos = [recognizer locationInView:self.view];
+ _mouseTapped = YES;
+}
+
+- (void)render
+{
+ ImGui::Render();
+}
+
+- (void)newFrame
+{
+ ImGuiIO& io = ImGui::GetIO();
+ ImGuiStyle &style = ImGui::GetStyle();
+
+ if (!g_FontTexture)
+ {
+ ImGui_ImplIOS_CreateDeviceObjects();
+ }
+
+ io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height );
+
+ io.MouseDrawCursor = g_synergyPtrActive;
+ if (g_synergyPtrActive)
+ {
+ style.TouchExtraPadding = ImVec2( 0.0, 0.0 );
+ io.MousePos = ImVec2( g_mousePosX, g_mousePosY );
+ for (int i=0; i < 3; i++)
+ {
+ io.MouseDown[i] = g_MousePressed[i];
+ }
+
+ // This is an arbitrary scaling factor that works for me. Not sure what units these
+ // mousewheel values from synergy are supposed to be in
+ io.MouseWheel = g_mouseWheelY / 500.0;
+ }
+ else
+ {
+ // Synergy not active, use touch events
+ style.TouchExtraPadding = ImVec2( 4.0, 4.0 );
+ io.MousePos = ImVec2(_touchPos.x, _touchPos.y );
+ if ((_mouseDown) || (_mouseTapped))
+ {
+ io.MouseDown[0] = true;
+ _mouseTapped = NO;
+ }
+ else
+ {
+ io.MouseDown[0] = false;
+ }
+ }
+
+ ImGui::NewFrame();
+}
+@end
+
+// 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)
+// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES
+static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data)
+{
+ // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled
+ GLint last_program, last_texture;
+ glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+ glEnable(GL_BLEND);
+ glBlendEquation(GL_FUNC_ADD);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_SCISSOR_TEST);
+ glActiveTexture(GL_TEXTURE0);
+
+ // Setup orthographic projection matrix
+ const float width = ImGui::GetIO().DisplaySize.x;
+ const float height = ImGui::GetIO().DisplaySize.y;
+ const float ortho_projection[4][4] =
+ {
+ { 2.0f/width, 0.0f, 0.0f, 0.0f },
+ { 0.0f, 2.0f/-height, 0.0f, 0.0f },
+ { 0.0f, 0.0f, -1.0f, 0.0f },
+ { -1.0f, 1.0f, 0.0f, 1.0f },
+ };
+ glUseProgram(g_ShaderHandle);
+ glUniform1i(g_AttribLocationTex, 0);
+ glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
+ glBindVertexArray(g_VaoHandle);
+
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
+ {
+ ImDrawList* cmd_list = draw_data->CmdLists[n];
+ ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front();
+
+ glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
+ const int needed_vtx_size = cmd_list->VtxBuffer.Size * sizeof(ImDrawVert);
+ if (g_VboSize < needed_vtx_size)
+ {
+ // Grow our buffer if needed
+ g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert);
+ glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW);
+ }
+
+ unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
+ if (!vtx_data)
+ continue;
+ memcpy(vtx_data, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
+ {
+ const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
+ if (pcmd->UserCallback)
+ {
+ pcmd->UserCallback(cmd_list, pcmd);
+ }
+ else
+ {
+ glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId);
+ glScissor((int)(pcmd->ClipRect.x * g_displayScale),
+ (int)((height - pcmd->ClipRect.w) * g_displayScale),
+ (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale),
+ (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale));
+ glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer );
+ }
+ idx_buffer += pcmd->ElemCount;
+ }
+ }
+
+ // Restore modified state
+ glBindVertexArray(0);
+ glBindBuffer( GL_ARRAY_BUFFER, 0);
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_DEPTH_TEST);
+ glUseProgram(last_program);
+ glDisable(GL_SCISSOR_TEST);
+ glBindTexture(GL_TEXTURE_2D, last_texture);
+}
+
+void ImGui_ImplIOS_CreateFontsTexture()
+{
+ // Build texture atlas
+ ImGuiIO& io = ImGui::GetIO();
+ unsigned char* pixels;
+ int width, height;
+ io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader.
+
+ // Upload texture to graphics system
+ GLint last_texture;
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+ glGenTextures(1, &g_FontTexture);
+ glBindTexture(GL_TEXTURE_2D, g_FontTexture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+
+ // Store our identifier
+ io.Fonts->TexID = (void *)(intptr_t)g_FontTexture;
+
+ // Restore state
+ glBindTexture(GL_TEXTURE_2D, last_texture);
+}
+
+bool ImGui_ImplIOS_CreateDeviceObjects()
+{
+ const GLchar *vertex_shader =
+ "uniform mat4 ProjMtx;\n"
+ "attribute highp vec2 Position;\n"
+ "attribute highp vec2 UV;\n"
+ "attribute highp vec4 Color;\n"
+ "varying vec2 Frag_UV;\n"
+ "varying vec4 Frag_Color;\n"
+ "void main()\n"
+ "{\n"
+ " Frag_UV = UV;\n"
+ " Frag_Color = Color;\n"
+ " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
+ "}\n";
+
+ const GLchar* fragment_shader =
+ "uniform sampler2D Texture;\n"
+ "varying highp vec2 Frag_UV;\n"
+ "varying highp vec4 Frag_Color;\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n"
+ "}\n";
+
+ g_ShaderHandle = glCreateProgram();
+ g_VertHandle = glCreateShader(GL_VERTEX_SHADER);
+ g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER);
+ glShaderSource(g_VertHandle, 1, &vertex_shader, 0);
+ glShaderSource(g_FragHandle, 1, &fragment_shader, 0);
+ glCompileShader(g_VertHandle);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log);
+ NSLog(@"VERTEX Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glCompileShader(g_FragHandle);
+
+#if defined(DEBUG)
+ glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log);
+ NSLog(@"FRAGMENT Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glAttachShader(g_ShaderHandle, g_VertHandle);
+ glAttachShader(g_ShaderHandle, g_FragHandle);
+ glLinkProgram(g_ShaderHandle);
+
+ g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture");
+ g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx");
+ g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position");
+ g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV");
+ g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color");
+
+ glGenBuffers(1, &g_VboHandle);
+
+ glGenVertexArrays(1, &g_VaoHandle);
+ glBindVertexArray(g_VaoHandle);
+ glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
+ glEnableVertexAttribArray(g_AttribLocationPosition);
+ glEnableVertexAttribArray(g_AttribLocationUV);
+ glEnableVertexAttribArray(g_AttribLocationColor);
+
+#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
+ glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos));
+ glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv));
+ glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col));
+#undef OFFSETOF
+ glBindVertexArray(0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ ImGui_ImplIOS_CreateFontsTexture();
+
+ return true;
+}
diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m
new file mode 100644
index 0000000..faba099
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/main.m
@@ -0,0 +1,13 @@
+//
+// main.m
+// imguiex
+//
+
+#import
+#import "AppDelegate.h"
+
+int main(int argc, char * argv[]) {
+ @autoreleasepool {
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+ }
+}
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore
new file mode 100644
index 0000000..8feda89
--- /dev/null
+++ b/examples/apple_example/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+imguiex.xcodeproj/project.xcworkspace/
+imguiex.xcodeproj/xcuserdata/
\ No newline at end of file
diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md
new file mode 100644
index 0000000..339f6bf
--- /dev/null
+++ b/examples/apple_example/README.md
@@ -0,0 +1,41 @@
+# iOS / OSX example
+
+## Introduction
+
+This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device.
+
+It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy.
+
+Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active.
+
+## How to Use on iOS
+
+* In Synergy, go to Preferences, and uncheck "Use SSL encryption"
+* Run the example app.
+* Tap the "servername" button in the corner
+* Enter the name or the IP of your synergy host
+* If you had previously connected to a server, you may need to kill and re-start the app.
+
+## How to Build on OSX
+
+* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh)
+* Run the command: `brew install glfw3`
+* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme
+* Click `Run` button
+
+## Notes and TODOs
+
+Things that would be nice but I didn't get around to doing:
+
+* iOS software keyboard not supported for text inputs
+* iOS hardware (bluetooth) keyboards not supported
+* Graceful disconnect/reconnect from uSynergy.
+* Copy/Paste not well-supported
+
+## C++ on iOS / OSX
+
+ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension.
+
+Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer.
+
+In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly.
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h
new file mode 100644
index 0000000..82f1542
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.h
@@ -0,0 +1,13 @@
+//
+// AppDelegate.h
+// imguiex
+
+#import
+
+@interface AppDelegate : UIResponder
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m
new file mode 100644
index 0000000..ab83101
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.m
@@ -0,0 +1,41 @@
+//
+// AppDelegate.m
+// imguiex
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Override point for customization after application launch.
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
new file mode 100644
index 0000000..5717c00
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..90dfb2e
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h
new file mode 100644
index 0000000..3323cfd
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.h
@@ -0,0 +1,12 @@
+//
+// GameViewController.h
+// imguiex
+
+// This is the OpenGL Example template from XCode, modified to support ImGui
+
+#import
+#import
+
+@interface GameViewController : GLKViewController
+
+@end
diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m
new file mode 100644
index 0000000..e902f7a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.m
@@ -0,0 +1,481 @@
+//
+// GameViewController.m
+// imguiex
+//
+#import "GameViewController.h"
+#import
+
+#import "imgui_impl_ios.h"
+#import "debug_hud.h"
+
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
+
+#define SERVERNAME_KEY @"ServerName"
+
+#define SERVERNAME_ALERT_TAG (10)
+
+// Uniform index.
+enum
+{
+ UNIFORM_MODELVIEWPROJECTION_MATRIX,
+ UNIFORM_NORMAL_MATRIX,
+ UNIFORM_DIFFUSE_COLOR,
+
+ NUM_UNIFORMS
+};
+GLint uniforms[NUM_UNIFORMS];
+
+// Attribute index.
+enum
+{
+ ATTRIB_VERTEX,
+ ATTRIB_NORMAL,
+ NUM_ATTRIBUTES
+};
+
+GLfloat gCubeVertexData[216] =
+{
+ // Data layout for each line below is:
+ // positionX, positionY, positionZ, normalX, normalY, normalZ,
+ 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+
+ 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+
+ -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+
+ -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+
+ 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+
+ 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f
+};
+
+@interface GameViewController ()
+{
+ GLuint _program;
+
+ GLKMatrix4 _modelViewProjectionMatrix;
+ GLKMatrix3 _normalMatrix;
+ float _rotation;
+
+ GLuint _vertexArray;
+ GLuint _vertexBuffer;
+
+ DebugHUD _hud;
+}
+@property (strong, nonatomic) EAGLContext *context;
+@property (strong, nonatomic) GLKBaseEffect *effect;
+@property (strong, nonatomic) ImGuiHelper *imgui;
+@property (weak, nonatomic) IBOutlet UIButton *btnServername;
+
+@property (strong, nonatomic) NSString *serverName;
+
+- (IBAction)onServernameTapped:(id)sender;
+
+- (void)setupGL;
+- (void)tearDownGL;
+
+- (BOOL)loadShaders;
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file;
+- (BOOL)linkProgram:(GLuint)prog;
+- (BOOL)validateProgram:(GLuint)prog;
+@end
+
+@implementation GameViewController
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+
+ if (!self.context) {
+ NSLog(@"Failed to create ES context");
+ }
+
+ GLKView *view = (GLKView *)self.view;
+ view.context = self.context;
+ view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
+
+ [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
+
+ [self setupGL];
+
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ];
+ self.imgui = [[ImGuiHelper alloc] initWithView:self.view ];
+ if (self.serverName)
+ {
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+ [self.imgui connectServer: self.serverName ];
+ }
+
+ DebugHUD_InitDefaults( &_hud );
+}
+
+- (void)dealloc
+{
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+
+ if ([self isViewLoaded] && ([[self view] window] == nil)) {
+ self.view = nil;
+
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+ self.context = nil;
+ }
+
+ // Dispose of any resources that can be recreated.
+}
+
+
+- (BOOL)prefersStatusBarHidden {
+ return YES;
+}
+
+- (IBAction)onServernameTapped:(id)sender
+{
+ UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ];
+ alert.alertViewStyle = UIAlertViewStylePlainTextInput;
+ alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to
+ [alert show];
+}
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG))
+ {
+ // This is really janky. I usually just hardcode the servername since I'm building it anyway.
+ // If you want to properly handle updating the server, you'll want to tear down and recreate
+ // the usynergy stuff in connectServer
+ BOOL serverNameWasSet = self.serverName.length > 0;
+ NSString *serverName = [[alertView textFieldAtIndex:0] text];
+
+ if ([serverName length] > 0) {
+ self.serverName = serverName;
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ [userDefaults setObject:serverName forKey:SERVERNAME_KEY ];
+ [userDefaults synchronize];
+
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+
+ // If we hadn't previously connected, try now
+ if (!serverNameWasSet) {
+ [self.imgui connectServer:self.serverName];
+ }
+ else
+ {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated"
+ message:@"Restart the app to connect the server"
+ delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
+ [alert show];
+ }
+ }
+ }
+}
+
+- (void)setupGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ [self loadShaders];
+
+ self.effect = [[GLKBaseEffect alloc] init];
+ self.effect.light0.enabled = GL_TRUE;
+ self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f);
+
+ glEnable(GL_DEPTH_TEST);
+
+ glGenVertexArraysOES(1, &_vertexArray);
+ glBindVertexArrayOES(_vertexArray);
+
+ glGenBuffers(1, &_vertexBuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);
+
+ glEnableVertexAttribArray(GLKVertexAttribPosition);
+ glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
+ glEnableVertexAttribArray(GLKVertexAttribNormal);
+ glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
+
+ glBindVertexArrayOES(0);
+
+
+}
+
+- (void)tearDownGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ glDeleteBuffers(1, &_vertexBuffer);
+ glDeleteVertexArraysOES(1, &_vertexArray);
+
+ self.effect = nil;
+
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+}
+
+#pragma mark - GLKView and GLKViewController delegate methods
+
+- (void)update
+{
+ float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height);
+ GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
+
+ self.effect.transform.projectionMatrix = projectionMatrix;
+
+ GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);
+ baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
+
+ // Compute the model view matrix for the object rendered with GLKit
+ GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ self.effect.transform.modelviewMatrix = modelViewMatrix;
+
+ // Compute the model view matrix for the object rendered with ES2
+ modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
+
+ _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
+
+ _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0));
+}
+
+
+- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
+{
+ glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glBindVertexArrayOES(_vertexArray);
+
+ // Render the object with GLKit
+ [self.effect prepareToDraw];
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ // Render the object again with ES2
+ glUseProgram(_program);
+
+ glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
+ glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
+ glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] );
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ [self.imgui newFrame];
+
+ // Now do our ImGUI UI
+ DebugHUD_DoInterface( &_hud );
+
+ self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f);
+
+ // Now render Imgui
+ [self.imgui render];
+
+}
+
+#pragma mark - OpenGL ES 2 shader compilation
+
+- (BOOL)loadShaders
+{
+ GLuint vertShader, fragShader;
+ NSString *vertShaderPathname, *fragShaderPathname;
+
+ // Create shader program.
+ _program = glCreateProgram();
+
+ // Create and compile vertex shader.
+ vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
+ if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
+ NSLog(@"Failed to compile vertex shader");
+ return NO;
+ }
+
+ // Create and compile fragment shader.
+ fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
+ if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
+ NSLog(@"Failed to compile fragment shader");
+ return NO;
+ }
+
+ // Attach vertex shader to program.
+ glAttachShader(_program, vertShader);
+
+ // Attach fragment shader to program.
+ glAttachShader(_program, fragShader);
+
+ // Bind attribute locations.
+ // This needs to be done prior to linking.
+ glBindAttribLocation(_program, GLKVertexAttribPosition, "position");
+ glBindAttribLocation(_program, GLKVertexAttribNormal, "normal");
+
+ // Link program.
+ if (![self linkProgram:_program]) {
+ NSLog(@"Failed to link program: %d", _program);
+
+ if (vertShader) {
+ glDeleteShader(vertShader);
+ vertShader = 0;
+ }
+ if (fragShader) {
+ glDeleteShader(fragShader);
+ fragShader = 0;
+ }
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+
+ return NO;
+ }
+
+ // Get uniform locations.
+ uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix");
+ uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix");
+ uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor");
+
+ // Release vertex and fragment shaders.
+ if (vertShader) {
+ glDetachShader(_program, vertShader);
+ glDeleteShader(vertShader);
+ }
+ if (fragShader) {
+ glDetachShader(_program, fragShader);
+ glDeleteShader(fragShader);
+ }
+
+ return YES;
+}
+
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
+{
+ GLint status;
+ const GLchar *source;
+
+ source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
+ if (!source) {
+ NSLog(@"Failed to load vertex shader");
+ return NO;
+ }
+
+ *shader = glCreateShader(type);
+ glShaderSource(*shader, 1, &source, NULL);
+ glCompileShader(*shader);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(*shader, logLength, &logLength, log);
+ NSLog(@"Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
+ if (status == 0) {
+ glDeleteShader(*shader);
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)linkProgram:(GLuint)prog
+{
+ GLint status;
+ glLinkProgram(prog);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program link log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetProgramiv(prog, GL_LINK_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)validateProgram:(GLuint)prog
+{
+ GLint logLength, status;
+
+ glValidateProgram(prog);
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program validate log:\n%s", log);
+ free(log);
+ }
+
+ glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..06b60d8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,77 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@2x~iphone.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@3x~iphone.png",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76~ipad.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76@2x~ipad.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "83.5x83.5",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
new file mode 100644
index 0000000..d728bc3
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
new file mode 100644
index 0000000..f48b799
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
new file mode 100644
index 0000000..67b08b8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
new file mode 100644
index 0000000..ae88e04
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist
new file mode 100644
index 0000000..bc6f548
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Info.plist
@@ -0,0 +1,49 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ org.imgui.example.$(PRODUCT_NAME:rfc1034identifier)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UIStatusBarHidden
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh
new file mode 100644
index 0000000..4000524
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh
@@ -0,0 +1,10 @@
+//
+// Shader.fsh
+// imguiex
+
+varying lowp vec4 colorVarying;
+
+void main()
+{
+ gl_FragColor = colorVarying;
+}
diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh
new file mode 100644
index 0000000..313c3d7
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh
@@ -0,0 +1,25 @@
+//
+// Shader.vsh
+// imguiex
+
+attribute vec4 position;
+attribute vec3 normal;
+
+varying lowp vec4 colorVarying;
+
+uniform vec3 diffuseColor;
+uniform mat4 modelViewProjectionMatrix;
+uniform mat3 normalMatrix;
+
+void main()
+{
+ vec3 eyeNormal = normalize(normalMatrix * normal);
+ vec3 lightPosition = vec3(0.0, 0.0, 1.0);
+
+ float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition)));
+
+ vec3 colorLit = diffuseColor * nDotVP;
+ colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 );
+
+ gl_Position = modelViewProjectionMatrix * position;
+}
diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp
new file mode 100644
index 0000000..c75938a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/debug_hud.cpp
@@ -0,0 +1,45 @@
+//
+// debug_hud.cpp
+// imguiex
+
+#include
+
+#include "debug_hud.h"
+#include "imgui.h"
+
+void DebugHUD_InitDefaults( DebugHUD *hud )
+{
+ hud->show_test_window = true;
+ hud->show_example_window = true;
+ hud->rotation_speed = 15.0f;
+
+ hud->cubeColor1[0] = 0.4f;
+ hud->cubeColor1[1] = 0.4f;
+ hud->cubeColor1[2] = 1.0f;
+ hud->cubeColor1[3] = 1.0f;
+
+ hud->cubeColor2[0] = 1.0f;
+ hud->cubeColor2[1] = 0.4f;
+ hud->cubeColor2[2] = 0.4f;
+ hud->cubeColor2[3] = 1.0f;
+}
+
+void DebugHUD_DoInterface( DebugHUD *hud )
+{
+ if (hud->show_test_window)
+ {
+ ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver );
+ ImGui::ShowTestWindow( &hud->show_test_window );
+ }
+
+ if (hud->show_example_window)
+ {
+ ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver );
+ ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver );
+ ImGui::Begin("Another Window", &hud->show_example_window);
+ ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1);
+ ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2);
+ ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f);
+ ImGui::End();
+ }
+}
diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h
new file mode 100644
index 0000000..17122f5
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/debug_hud.h
@@ -0,0 +1,25 @@
+//
+// debug_hud.h
+// imguiex
+
+#pragma once
+
+typedef struct DebugHUD
+{
+ bool show_test_window;
+ bool show_example_window;
+ float rotation_speed;
+ float cubeColor1[4];
+ float cubeColor2[4];
+} DebugHUD;
+
+#if __cplusplus
+extern "C" {
+#endif
+
+void DebugHUD_InitDefaults( DebugHUD *hud );
+void DebugHUD_DoInterface( DebugHUD *hud );
+
+#if __cplusplus
+}
+#endif
diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png
new file mode 100644
index 0000000..820e4d7
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h
new file mode 100644
index 0000000..9b01dd3
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h
@@ -0,0 +1,22 @@
+// ImGui iOS+OpenGL+Synergy binding
+// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much.
+// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application.
+
+// by Joel Davis (joeld42@gmail.com)
+
+#pragma once
+
+#include
+#include
+
+@interface ImGuiHelper : NSObject
+
+- (id) initWithView: (UIView *)view;
+
+- (void)connectServer: (NSString*)serverName;
+
+- (void)render;
+- (void)newFrame;
+
+@end
diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm
new file mode 100644
index 0000000..893dbf9
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm
@@ -0,0 +1,806 @@
+// ImGui iOS+OpenGL+Synergy binding
+// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much.
+// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application.
+
+// TODO:
+// - Clipboard is not supported.
+
+#import
+#import
+
+#include
+#include
+#include
+#include
+
+#include "imgui_impl_ios.h"
+#include "imgui.h"
+
+#include "uSynergy.h"
+
+// From Carbon HIToolbox/Events.h
+// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247
+enum {
+ kVK_ANSI_A = 0x00,
+ kVK_ANSI_S = 0x01,
+ kVK_ANSI_D = 0x02,
+ kVK_ANSI_F = 0x03,
+ kVK_ANSI_H = 0x04,
+ kVK_ANSI_G = 0x05,
+ kVK_ANSI_Z = 0x06,
+ kVK_ANSI_X = 0x07,
+ kVK_ANSI_C = 0x08,
+ kVK_ANSI_V = 0x09,
+ kVK_ANSI_B = 0x0B,
+ kVK_ANSI_Q = 0x0C,
+ kVK_ANSI_W = 0x0D,
+ kVK_ANSI_E = 0x0E,
+ kVK_ANSI_R = 0x0F,
+ kVK_ANSI_Y = 0x10,
+ kVK_ANSI_T = 0x11,
+ kVK_ANSI_1 = 0x12,
+ kVK_ANSI_2 = 0x13,
+ kVK_ANSI_3 = 0x14,
+ kVK_ANSI_4 = 0x15,
+ kVK_ANSI_6 = 0x16,
+ kVK_ANSI_5 = 0x17,
+ kVK_ANSI_Equal = 0x18,
+ kVK_ANSI_9 = 0x19,
+ kVK_ANSI_7 = 0x1A,
+ kVK_ANSI_Minus = 0x1B,
+ kVK_ANSI_8 = 0x1C,
+ kVK_ANSI_0 = 0x1D,
+ kVK_ANSI_RightBracket = 0x1E,
+ kVK_ANSI_O = 0x1F,
+ kVK_ANSI_U = 0x20,
+ kVK_ANSI_LeftBracket = 0x21,
+ kVK_ANSI_I = 0x22,
+ kVK_ANSI_P = 0x23,
+ kVK_ANSI_L = 0x25,
+ kVK_ANSI_J = 0x26,
+ kVK_ANSI_Quote = 0x27,
+ kVK_ANSI_K = 0x28,
+ kVK_ANSI_Semicolon = 0x29,
+ kVK_ANSI_Backslash = 0x2A,
+ kVK_ANSI_Comma = 0x2B,
+ kVK_ANSI_Slash = 0x2C,
+ kVK_ANSI_N = 0x2D,
+ kVK_ANSI_M = 0x2E,
+ kVK_ANSI_Period = 0x2F,
+ kVK_ANSI_Grave = 0x32,
+ kVK_ANSI_KeypadDecimal = 0x41,
+ kVK_ANSI_KeypadMultiply = 0x43,
+ kVK_ANSI_KeypadPlus = 0x45,
+ kVK_ANSI_KeypadClear = 0x47,
+ kVK_ANSI_KeypadDivide = 0x4B,
+ kVK_ANSI_KeypadEnter = 0x4C,
+ kVK_ANSI_KeypadMinus = 0x4E,
+ kVK_ANSI_KeypadEquals = 0x51,
+ kVK_ANSI_Keypad0 = 0x52,
+ kVK_ANSI_Keypad1 = 0x53,
+ kVK_ANSI_Keypad2 = 0x54,
+ kVK_ANSI_Keypad3 = 0x55,
+ kVK_ANSI_Keypad4 = 0x56,
+ kVK_ANSI_Keypad5 = 0x57,
+ kVK_ANSI_Keypad6 = 0x58,
+ kVK_ANSI_Keypad7 = 0x59,
+ kVK_ANSI_Keypad8 = 0x5B,
+ kVK_ANSI_Keypad9 = 0x5C
+};
+
+/* keycodes for keys that are independent of keyboard layout*/
+enum {
+ kVK_Return = 0x24,
+ kVK_Tab = 0x30,
+ kVK_Space = 0x31,
+ kVK_Delete = 0x33,
+ kVK_Escape = 0x35,
+ kVK_Command = 0x37,
+ kVK_Shift = 0x38,
+ kVK_CapsLock = 0x39,
+ kVK_Option = 0x3A,
+ kVK_Control = 0x3B,
+ kVK_RightShift = 0x3C,
+ kVK_RightOption = 0x3D,
+ kVK_RightControl = 0x3E,
+ kVK_Function = 0x3F,
+ kVK_F17 = 0x40,
+ kVK_VolumeUp = 0x48,
+ kVK_VolumeDown = 0x49,
+ kVK_Mute = 0x4A,
+ kVK_F18 = 0x4F,
+ kVK_F19 = 0x50,
+ kVK_F20 = 0x5A,
+ kVK_F5 = 0x60,
+ kVK_F6 = 0x61,
+ kVK_F7 = 0x62,
+ kVK_F3 = 0x63,
+ kVK_F8 = 0x64,
+ kVK_F9 = 0x65,
+ kVK_F11 = 0x67,
+ kVK_F13 = 0x69,
+ kVK_F16 = 0x6A,
+ kVK_F14 = 0x6B,
+ kVK_F10 = 0x6D,
+ kVK_F12 = 0x6F,
+ kVK_F15 = 0x71,
+ kVK_Help = 0x72,
+ kVK_Home = 0x73,
+ kVK_PageUp = 0x74,
+ kVK_ForwardDelete = 0x75,
+ kVK_F4 = 0x76,
+ kVK_End = 0x77,
+ kVK_F2 = 0x78,
+ kVK_PageDown = 0x79,
+ kVK_F1 = 0x7A,
+ kVK_LeftArrow = 0x7B,
+ kVK_RightArrow = 0x7C,
+ kVK_DownArrow = 0x7D,
+ kVK_UpArrow = 0x7E
+};
+
+static char g_keycodeCharUnshifted[256] = {};
+static char g_keycodeCharShifted[256] = {};
+
+//static double g_Time = 0.0f;
+static bool g_MousePressed[3] = { false, false, false };
+static float g_mouseWheelX = 0.0f;
+static float g_mouseWheelY = 0.0f;
+
+static GLuint g_FontTexture = 0;
+static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0;
+static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0;
+static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0;
+static size_t g_VboSize = 0;
+static unsigned int g_VboHandle = 0, g_VaoHandle = 0;
+static float g_displayScale;
+
+static int usynergy_sockfd;
+static bool g_synergyPtrActive = false;
+static uint16_t g_mousePosX = 0;
+static uint16_t g_mousePosY = 0;
+
+static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data);
+bool ImGui_ImplIOS_CreateDeviceObjects();
+
+static NSString *g_serverName;
+
+uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie)
+{
+ // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since
+ // uSynergy does not support SSL.
+
+ NSLog( @"Connect Func!");
+ struct addrinfo hints, *res;
+
+ // first, load up address structs with getaddrinfo():
+ memset(&hints, 0, sizeof hints);
+ hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
+ hints.ai_socktype = SOCK_STREAM;
+
+ // get server address
+ getaddrinfo([g_serverName UTF8String], "24800", &hints, &res);
+
+ if (!res)
+ {
+ NSLog( @"Could not find server: %@", g_serverName );
+ return USYNERGY_FALSE;
+ }
+
+ // make a socket:
+ usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+
+ // connect it to the address and port we passed in to getaddrinfo():
+ int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen);
+ if (!ret) {
+ NSLog( @"Connect succeeded...");
+ } else {
+ NSLog( @"Connect failed, %d", ret );
+ }
+
+
+ return USYNERGY_TRUE;
+}
+
+uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length)
+{
+// NSLog( @"Send Func" );
+ send( usynergy_sockfd, buffer, length, 0 );
+
+ return USYNERGY_TRUE;
+}
+
+uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength)
+{
+ *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 );
+
+ return USYNERGY_TRUE;
+}
+
+void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs)
+{
+ usleep( timeMs * 1000 );
+}
+
+uint32_t ImGui_GetTimeFunc()
+{
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+
+ return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000);
+}
+
+void ImGui_TraceFunc(uSynergyCookie cookie, const char *text)
+{
+ puts(text);
+}
+
+void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active)
+{
+ g_synergyPtrActive = active;
+// printf( "Synergy: screen activate %s\n", active?"YES":"NO" );
+}
+
+void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY,
+ uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle)
+{
+// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY );
+ uSynergyContext *ctx = (uSynergyContext*)cookie;
+ g_mousePosX = x;
+ g_mousePosY = y;
+ g_mouseWheelX = wheelX;
+ g_mouseWheelY = wheelY;
+ g_MousePressed[0] = buttonLeft;
+ g_MousePressed[1] = buttonMiddle;
+ g_MousePressed[2] = buttonRight;
+
+ ctx->m_mouseWheelX = 0;
+ ctx->m_mouseWheelY = 0;
+}
+
+void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key,
+ uint16_t modifiers, uSynergyBool down, uSynergyBool repeat)
+{
+ int scanCode = key-1;
+// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false");
+ ImGuiIO& io = ImGui::GetIO();
+ io.KeysDown[key] = down;
+ io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT);
+ io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL);
+ io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT);
+ io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN);
+
+ // Add this as keyboard input
+ if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL))
+ {
+ // If this key maps to a character input, apply it
+ int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode];
+ io.AddInputCharacter((unsigned short)charForKeycode);
+ }
+
+}
+
+void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY)
+{
+ printf("Synergy: joystick callback TODO\n");
+}
+
+void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size)
+{
+ printf("Synergy: clipboard callback TODO\n" );
+}
+
+@interface ImGuiHelper ()
+{
+ BOOL _mouseDown;
+ BOOL _mouseTapped;
+ CGPoint _touchPos;
+
+ uSynergyContext _synergyCtx;
+ dispatch_queue_t _synergyQueue;
+}
+@property (nonatomic, weak) UIView *view;
+@property (nonatomic, strong) NSString *serverName;
+
+@end
+
+@implementation ImGuiHelper
+
+- (id) initWithView: (UIView *)view
+{
+ self = [super init];
+ if (self)
+ {
+ self.view = view;
+
+ [self setupImGuiHooks];
+ }
+ return self;
+}
+
+- (void)setupKeymaps
+{
+ // The keyboard mapping is a big headache. I tried for a while to find a better way to do this,
+ // but this was the best I could come up with. There are some device independent API's available
+ // to convert scan codes to unicode characters, but these are only available on mac and not
+ // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do
+ // this or any way to get the character codes out of usynergy.
+ g_keycodeCharUnshifted[ kVK_ANSI_A ]='a';
+ g_keycodeCharUnshifted[ kVK_ANSI_S ]='s';
+ g_keycodeCharUnshifted[ kVK_ANSI_D ]='d';
+ g_keycodeCharUnshifted[ kVK_ANSI_F ]='f';
+ g_keycodeCharUnshifted[ kVK_ANSI_H ]='h';
+ g_keycodeCharUnshifted[ kVK_ANSI_G ]='g';
+ g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z';
+ g_keycodeCharUnshifted[ kVK_ANSI_X ]='x';
+ g_keycodeCharUnshifted[ kVK_ANSI_C ]='c';
+ g_keycodeCharUnshifted[ kVK_ANSI_V ]='v';
+ g_keycodeCharUnshifted[ kVK_ANSI_B ]='b';
+ g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q';
+ g_keycodeCharUnshifted[ kVK_ANSI_W ]='w';
+ g_keycodeCharUnshifted[ kVK_ANSI_E ]='e';
+ g_keycodeCharUnshifted[ kVK_ANSI_R ]='r';
+ g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y';
+ g_keycodeCharUnshifted[ kVK_ANSI_T ]='t';
+ g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1';
+ g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2';
+ g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3';
+ g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4';
+ g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6';
+ g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5';
+ g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='=';
+ g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9';
+ g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7';
+ g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-';
+ g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8';
+ g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0';
+ g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']';
+ g_keycodeCharUnshifted[ kVK_ANSI_O ]='o';
+ g_keycodeCharUnshifted[ kVK_ANSI_U ]='u';
+ g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='[';
+ g_keycodeCharUnshifted[ kVK_ANSI_I ]='i';
+ g_keycodeCharUnshifted[ kVK_ANSI_P ]='p';
+ g_keycodeCharUnshifted[ kVK_ANSI_L ]='l';
+ g_keycodeCharUnshifted[ kVK_ANSI_J ]='j';
+ g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\'';
+ g_keycodeCharUnshifted[ kVK_ANSI_K ]='k';
+ g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';';
+ g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\';
+ g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=',';
+ g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/';
+ g_keycodeCharUnshifted[ kVK_ANSI_N ]='n';
+ g_keycodeCharUnshifted[ kVK_ANSI_M ]='m';
+ g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.';
+ g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='=';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9';
+ g_keycodeCharUnshifted[ kVK_Space ]=' ';
+
+ g_keycodeCharShifted[ kVK_ANSI_A ]='A';
+ g_keycodeCharShifted[ kVK_ANSI_S ]='S';
+ g_keycodeCharShifted[ kVK_ANSI_D ]='D';
+ g_keycodeCharShifted[ kVK_ANSI_F ]='F';
+ g_keycodeCharShifted[ kVK_ANSI_H ]='H';
+ g_keycodeCharShifted[ kVK_ANSI_G ]='G';
+ g_keycodeCharShifted[ kVK_ANSI_Z ]='Z';
+ g_keycodeCharShifted[ kVK_ANSI_X ]='X';
+ g_keycodeCharShifted[ kVK_ANSI_C ]='C';
+ g_keycodeCharShifted[ kVK_ANSI_V ]='V';
+ g_keycodeCharShifted[ kVK_ANSI_B ]='B';
+ g_keycodeCharShifted[ kVK_ANSI_Q ]='Q';
+ g_keycodeCharShifted[ kVK_ANSI_W ]='W';
+ g_keycodeCharShifted[ kVK_ANSI_E ]='E';
+ g_keycodeCharShifted[ kVK_ANSI_R ]='R';
+ g_keycodeCharShifted[ kVK_ANSI_Y ]='Y';
+ g_keycodeCharShifted[ kVK_ANSI_T ]='T';
+ g_keycodeCharShifted[ kVK_ANSI_1 ]='!';
+ g_keycodeCharShifted[ kVK_ANSI_2 ]='@';
+ g_keycodeCharShifted[ kVK_ANSI_3 ]='#';
+ g_keycodeCharShifted[ kVK_ANSI_4 ]='$';
+ g_keycodeCharShifted[ kVK_ANSI_6 ]='^';
+ g_keycodeCharShifted[ kVK_ANSI_5 ]='%';
+ g_keycodeCharShifted[ kVK_ANSI_Equal ]='+';
+ g_keycodeCharShifted[ kVK_ANSI_9 ]='(';
+ g_keycodeCharShifted[ kVK_ANSI_7 ]='&';
+ g_keycodeCharShifted[ kVK_ANSI_Minus ]='_';
+ g_keycodeCharShifted[ kVK_ANSI_8 ]='*';
+ g_keycodeCharShifted[ kVK_ANSI_0 ]=')';
+ g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}';
+ g_keycodeCharShifted[ kVK_ANSI_O ]='O';
+ g_keycodeCharShifted[ kVK_ANSI_U ]='U';
+ g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{';
+ g_keycodeCharShifted[ kVK_ANSI_I ]='I';
+ g_keycodeCharShifted[ kVK_ANSI_P ]='P';
+ g_keycodeCharShifted[ kVK_ANSI_L ]='L';
+ g_keycodeCharShifted[ kVK_ANSI_J ]='J';
+ g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"';
+ g_keycodeCharShifted[ kVK_ANSI_K ]='K';
+ g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':';
+ g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|';
+ g_keycodeCharShifted[ kVK_ANSI_Comma ]='<';
+ g_keycodeCharShifted[ kVK_ANSI_Slash ]='?';
+ g_keycodeCharShifted[ kVK_ANSI_N ]='N';
+ g_keycodeCharShifted[ kVK_ANSI_M ]='M';
+ g_keycodeCharShifted[ kVK_ANSI_Period ]='>';
+ g_keycodeCharShifted[ kVK_ANSI_Grave ]='~';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='=';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9';
+ g_keycodeCharShifted[ kVK_Space ]=' ';
+}
+
+- (void)setupImGuiHooks
+{
+ ImGuiIO &io = ImGui::GetIO();
+
+ [self setupKeymaps];
+
+ // Account for retina display for glScissor
+ g_displayScale = [[UIScreen mainScreen] scale];
+
+ ImGuiStyle &style = ImGui::GetStyle();
+ style.TouchExtraPadding = ImVec2( 4.0, 4.0 );
+
+ io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists;
+
+ UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ];
+ [self.view addGestureRecognizer:panRecognizer];
+
+ UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)];
+ [self.view addGestureRecognizer:tapRecoginzer];
+
+ // Fill out the Synergy key map
+ // (for some reason synergy scan codes are off by 1)
+ io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1;
+ io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1;
+ io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1;
+ io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1;
+ io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1;
+ io.KeyMap[ImGuiKey_Home] = kVK_Home+1;
+ io.KeyMap[ImGuiKey_End] = kVK_End+1;
+ io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1;
+ io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1;
+ io.KeyMap[ImGuiKey_Enter] = kVK_Return+1;
+ io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1;
+ io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1;
+ io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1;
+ io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1;
+ io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1;
+ io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1;
+ io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1;
+}
+
+- (void)connectServer: (NSString*)serverName
+{
+ self.serverName = serverName;
+ g_serverName = serverName;
+
+ // Init synergy
+ NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey];
+
+ uSynergyInit( &_synergyCtx );
+ _synergyCtx.m_clientName = strdup( [bundleName UTF8String] );
+ _synergyCtx.m_clientWidth = self.view.bounds.size.width;
+ _synergyCtx.m_clientHeight = self.view.bounds.size.height;
+
+ _synergyCtx.m_connectFunc = ImGui_ConnectFunc;
+ _synergyCtx.m_sendFunc = ImGui_SendFunc;
+ _synergyCtx.m_receiveFunc = ImGui_RecvFunc;
+ _synergyCtx.m_sleepFunc = ImGui_SleepFunc;
+ _synergyCtx.m_traceFunc = ImGui_TraceFunc;
+ _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc;
+
+ _synergyCtx.m_traceFunc = ImGui_TraceFunc;
+ _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback;
+ _synergyCtx.m_mouseCallback = ImGui_MouseCallback;
+ _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback;
+
+ _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx;
+
+ // Create a background thread for synergy
+ _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL );
+ dispatch_async( _synergyQueue, ^{
+ while (1) {
+ uSynergyUpdate( &_synergyCtx );
+ }
+ });
+}
+
+
+- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer
+{
+
+ if ((recognizer.state == UIGestureRecognizerStateBegan) ||
+ (recognizer.state == UIGestureRecognizerStateChanged))
+ {
+ _mouseDown = YES;
+ _touchPos = [recognizer locationInView:self.view];
+ }
+ else
+ {
+ _mouseDown = NO;
+ _touchPos = CGPointMake( -1, -1 );
+ }
+}
+
+- (void)viewDidTap: (UITapGestureRecognizer*)recognizer
+{
+ _touchPos = [recognizer locationInView:self.view];
+ _mouseTapped = YES;
+}
+
+- (void)render
+{
+ ImGui::Render();
+}
+
+- (void)newFrame
+{
+ ImGuiIO& io = ImGui::GetIO();
+ ImGuiStyle &style = ImGui::GetStyle();
+
+ if (!g_FontTexture)
+ {
+ ImGui_ImplIOS_CreateDeviceObjects();
+ }
+
+ io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height );
+
+ io.MouseDrawCursor = g_synergyPtrActive;
+ if (g_synergyPtrActive)
+ {
+ style.TouchExtraPadding = ImVec2( 0.0, 0.0 );
+ io.MousePos = ImVec2( g_mousePosX, g_mousePosY );
+ for (int i=0; i < 3; i++)
+ {
+ io.MouseDown[i] = g_MousePressed[i];
+ }
+
+ // This is an arbitrary scaling factor that works for me. Not sure what units these
+ // mousewheel values from synergy are supposed to be in
+ io.MouseWheel = g_mouseWheelY / 500.0;
+ }
+ else
+ {
+ // Synergy not active, use touch events
+ style.TouchExtraPadding = ImVec2( 4.0, 4.0 );
+ io.MousePos = ImVec2(_touchPos.x, _touchPos.y );
+ if ((_mouseDown) || (_mouseTapped))
+ {
+ io.MouseDown[0] = true;
+ _mouseTapped = NO;
+ }
+ else
+ {
+ io.MouseDown[0] = false;
+ }
+ }
+
+ ImGui::NewFrame();
+}
+@end
+
+// 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)
+// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES
+static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data)
+{
+ // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled
+ GLint last_program, last_texture;
+ glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+ glEnable(GL_BLEND);
+ glBlendEquation(GL_FUNC_ADD);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_SCISSOR_TEST);
+ glActiveTexture(GL_TEXTURE0);
+
+ // Setup orthographic projection matrix
+ const float width = ImGui::GetIO().DisplaySize.x;
+ const float height = ImGui::GetIO().DisplaySize.y;
+ const float ortho_projection[4][4] =
+ {
+ { 2.0f/width, 0.0f, 0.0f, 0.0f },
+ { 0.0f, 2.0f/-height, 0.0f, 0.0f },
+ { 0.0f, 0.0f, -1.0f, 0.0f },
+ { -1.0f, 1.0f, 0.0f, 1.0f },
+ };
+ glUseProgram(g_ShaderHandle);
+ glUniform1i(g_AttribLocationTex, 0);
+ glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
+ glBindVertexArray(g_VaoHandle);
+
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
+ {
+ ImDrawList* cmd_list = draw_data->CmdLists[n];
+ ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front();
+
+ glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
+ const int needed_vtx_size = cmd_list->VtxBuffer.Size * sizeof(ImDrawVert);
+ if (g_VboSize < needed_vtx_size)
+ {
+ // Grow our buffer if needed
+ g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert);
+ glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW);
+ }
+
+ unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
+ if (!vtx_data)
+ continue;
+ memcpy(vtx_data, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
+ {
+ const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
+ if (pcmd->UserCallback)
+ {
+ pcmd->UserCallback(cmd_list, pcmd);
+ }
+ else
+ {
+ glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId);
+ glScissor((int)(pcmd->ClipRect.x * g_displayScale),
+ (int)((height - pcmd->ClipRect.w) * g_displayScale),
+ (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale),
+ (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale));
+ glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer );
+ }
+ idx_buffer += pcmd->ElemCount;
+ }
+ }
+
+ // Restore modified state
+ glBindVertexArray(0);
+ glBindBuffer( GL_ARRAY_BUFFER, 0);
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_DEPTH_TEST);
+ glUseProgram(last_program);
+ glDisable(GL_SCISSOR_TEST);
+ glBindTexture(GL_TEXTURE_2D, last_texture);
+}
+
+void ImGui_ImplIOS_CreateFontsTexture()
+{
+ // Build texture atlas
+ ImGuiIO& io = ImGui::GetIO();
+ unsigned char* pixels;
+ int width, height;
+ io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader.
+
+ // Upload texture to graphics system
+ GLint last_texture;
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+ glGenTextures(1, &g_FontTexture);
+ glBindTexture(GL_TEXTURE_2D, g_FontTexture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+
+ // Store our identifier
+ io.Fonts->TexID = (void *)(intptr_t)g_FontTexture;
+
+ // Restore state
+ glBindTexture(GL_TEXTURE_2D, last_texture);
+}
+
+bool ImGui_ImplIOS_CreateDeviceObjects()
+{
+ const GLchar *vertex_shader =
+ "uniform mat4 ProjMtx;\n"
+ "attribute highp vec2 Position;\n"
+ "attribute highp vec2 UV;\n"
+ "attribute highp vec4 Color;\n"
+ "varying vec2 Frag_UV;\n"
+ "varying vec4 Frag_Color;\n"
+ "void main()\n"
+ "{\n"
+ " Frag_UV = UV;\n"
+ " Frag_Color = Color;\n"
+ " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
+ "}\n";
+
+ const GLchar* fragment_shader =
+ "uniform sampler2D Texture;\n"
+ "varying highp vec2 Frag_UV;\n"
+ "varying highp vec4 Frag_Color;\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n"
+ "}\n";
+
+ g_ShaderHandle = glCreateProgram();
+ g_VertHandle = glCreateShader(GL_VERTEX_SHADER);
+ g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER);
+ glShaderSource(g_VertHandle, 1, &vertex_shader, 0);
+ glShaderSource(g_FragHandle, 1, &fragment_shader, 0);
+ glCompileShader(g_VertHandle);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log);
+ NSLog(@"VERTEX Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glCompileShader(g_FragHandle);
+
+#if defined(DEBUG)
+ glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log);
+ NSLog(@"FRAGMENT Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glAttachShader(g_ShaderHandle, g_VertHandle);
+ glAttachShader(g_ShaderHandle, g_FragHandle);
+ glLinkProgram(g_ShaderHandle);
+
+ g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture");
+ g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx");
+ g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position");
+ g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV");
+ g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color");
+
+ glGenBuffers(1, &g_VboHandle);
+
+ glGenVertexArrays(1, &g_VaoHandle);
+ glBindVertexArray(g_VaoHandle);
+ glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
+ glEnableVertexAttribArray(g_AttribLocationPosition);
+ glEnableVertexAttribArray(g_AttribLocationUV);
+ glEnableVertexAttribArray(g_AttribLocationColor);
+
+#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
+ glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos));
+ glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv));
+ glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col));
+#undef OFFSETOF
+ glBindVertexArray(0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ ImGui_ImplIOS_CreateFontsTexture();
+
+ return true;
+}
diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m
new file mode 100644
index 0000000..faba099
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/main.m
@@ -0,0 +1,13 @@
+//
+// main.m
+// imguiex
+//
+
+#import
+#import "AppDelegate.h"
+
+int main(int argc, char * argv[]) {
+ @autoreleasepool {
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+ }
+}
diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h
new file mode 100644
index 0000000..33d199b
--- /dev/null
+++ b/examples/apple_example/imguiex-osx/AppDelegate.h
@@ -0,0 +1,15 @@
+//
+// AppDelegate.h
+// imguiex-osx
+//
+// Created by James Chen on 4/5/16.
+// Copyright © 2016 Joel Davis. All rights reserved.
+//
+
+#import
+
+@interface AppDelegate : NSObject
+
+
+@end
+
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore
new file mode 100644
index 0000000..8feda89
--- /dev/null
+++ b/examples/apple_example/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+imguiex.xcodeproj/project.xcworkspace/
+imguiex.xcodeproj/xcuserdata/
\ No newline at end of file
diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md
new file mode 100644
index 0000000..339f6bf
--- /dev/null
+++ b/examples/apple_example/README.md
@@ -0,0 +1,41 @@
+# iOS / OSX example
+
+## Introduction
+
+This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device.
+
+It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy.
+
+Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active.
+
+## How to Use on iOS
+
+* In Synergy, go to Preferences, and uncheck "Use SSL encryption"
+* Run the example app.
+* Tap the "servername" button in the corner
+* Enter the name or the IP of your synergy host
+* If you had previously connected to a server, you may need to kill and re-start the app.
+
+## How to Build on OSX
+
+* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh)
+* Run the command: `brew install glfw3`
+* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme
+* Click `Run` button
+
+## Notes and TODOs
+
+Things that would be nice but I didn't get around to doing:
+
+* iOS software keyboard not supported for text inputs
+* iOS hardware (bluetooth) keyboards not supported
+* Graceful disconnect/reconnect from uSynergy.
+* Copy/Paste not well-supported
+
+## C++ on iOS / OSX
+
+ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension.
+
+Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer.
+
+In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly.
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h
new file mode 100644
index 0000000..82f1542
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.h
@@ -0,0 +1,13 @@
+//
+// AppDelegate.h
+// imguiex
+
+#import
+
+@interface AppDelegate : UIResponder
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m
new file mode 100644
index 0000000..ab83101
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.m
@@ -0,0 +1,41 @@
+//
+// AppDelegate.m
+// imguiex
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Override point for customization after application launch.
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
new file mode 100644
index 0000000..5717c00
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..90dfb2e
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h
new file mode 100644
index 0000000..3323cfd
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.h
@@ -0,0 +1,12 @@
+//
+// GameViewController.h
+// imguiex
+
+// This is the OpenGL Example template from XCode, modified to support ImGui
+
+#import
+#import
+
+@interface GameViewController : GLKViewController
+
+@end
diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m
new file mode 100644
index 0000000..e902f7a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.m
@@ -0,0 +1,481 @@
+//
+// GameViewController.m
+// imguiex
+//
+#import "GameViewController.h"
+#import
+
+#import "imgui_impl_ios.h"
+#import "debug_hud.h"
+
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
+
+#define SERVERNAME_KEY @"ServerName"
+
+#define SERVERNAME_ALERT_TAG (10)
+
+// Uniform index.
+enum
+{
+ UNIFORM_MODELVIEWPROJECTION_MATRIX,
+ UNIFORM_NORMAL_MATRIX,
+ UNIFORM_DIFFUSE_COLOR,
+
+ NUM_UNIFORMS
+};
+GLint uniforms[NUM_UNIFORMS];
+
+// Attribute index.
+enum
+{
+ ATTRIB_VERTEX,
+ ATTRIB_NORMAL,
+ NUM_ATTRIBUTES
+};
+
+GLfloat gCubeVertexData[216] =
+{
+ // Data layout for each line below is:
+ // positionX, positionY, positionZ, normalX, normalY, normalZ,
+ 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+
+ 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+
+ -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+
+ -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+
+ 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+
+ 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f
+};
+
+@interface GameViewController ()
+{
+ GLuint _program;
+
+ GLKMatrix4 _modelViewProjectionMatrix;
+ GLKMatrix3 _normalMatrix;
+ float _rotation;
+
+ GLuint _vertexArray;
+ GLuint _vertexBuffer;
+
+ DebugHUD _hud;
+}
+@property (strong, nonatomic) EAGLContext *context;
+@property (strong, nonatomic) GLKBaseEffect *effect;
+@property (strong, nonatomic) ImGuiHelper *imgui;
+@property (weak, nonatomic) IBOutlet UIButton *btnServername;
+
+@property (strong, nonatomic) NSString *serverName;
+
+- (IBAction)onServernameTapped:(id)sender;
+
+- (void)setupGL;
+- (void)tearDownGL;
+
+- (BOOL)loadShaders;
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file;
+- (BOOL)linkProgram:(GLuint)prog;
+- (BOOL)validateProgram:(GLuint)prog;
+@end
+
+@implementation GameViewController
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+
+ if (!self.context) {
+ NSLog(@"Failed to create ES context");
+ }
+
+ GLKView *view = (GLKView *)self.view;
+ view.context = self.context;
+ view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
+
+ [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
+
+ [self setupGL];
+
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ];
+ self.imgui = [[ImGuiHelper alloc] initWithView:self.view ];
+ if (self.serverName)
+ {
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+ [self.imgui connectServer: self.serverName ];
+ }
+
+ DebugHUD_InitDefaults( &_hud );
+}
+
+- (void)dealloc
+{
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+
+ if ([self isViewLoaded] && ([[self view] window] == nil)) {
+ self.view = nil;
+
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+ self.context = nil;
+ }
+
+ // Dispose of any resources that can be recreated.
+}
+
+
+- (BOOL)prefersStatusBarHidden {
+ return YES;
+}
+
+- (IBAction)onServernameTapped:(id)sender
+{
+ UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ];
+ alert.alertViewStyle = UIAlertViewStylePlainTextInput;
+ alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to
+ [alert show];
+}
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG))
+ {
+ // This is really janky. I usually just hardcode the servername since I'm building it anyway.
+ // If you want to properly handle updating the server, you'll want to tear down and recreate
+ // the usynergy stuff in connectServer
+ BOOL serverNameWasSet = self.serverName.length > 0;
+ NSString *serverName = [[alertView textFieldAtIndex:0] text];
+
+ if ([serverName length] > 0) {
+ self.serverName = serverName;
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ [userDefaults setObject:serverName forKey:SERVERNAME_KEY ];
+ [userDefaults synchronize];
+
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+
+ // If we hadn't previously connected, try now
+ if (!serverNameWasSet) {
+ [self.imgui connectServer:self.serverName];
+ }
+ else
+ {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated"
+ message:@"Restart the app to connect the server"
+ delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
+ [alert show];
+ }
+ }
+ }
+}
+
+- (void)setupGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ [self loadShaders];
+
+ self.effect = [[GLKBaseEffect alloc] init];
+ self.effect.light0.enabled = GL_TRUE;
+ self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f);
+
+ glEnable(GL_DEPTH_TEST);
+
+ glGenVertexArraysOES(1, &_vertexArray);
+ glBindVertexArrayOES(_vertexArray);
+
+ glGenBuffers(1, &_vertexBuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);
+
+ glEnableVertexAttribArray(GLKVertexAttribPosition);
+ glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
+ glEnableVertexAttribArray(GLKVertexAttribNormal);
+ glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
+
+ glBindVertexArrayOES(0);
+
+
+}
+
+- (void)tearDownGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ glDeleteBuffers(1, &_vertexBuffer);
+ glDeleteVertexArraysOES(1, &_vertexArray);
+
+ self.effect = nil;
+
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+}
+
+#pragma mark - GLKView and GLKViewController delegate methods
+
+- (void)update
+{
+ float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height);
+ GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
+
+ self.effect.transform.projectionMatrix = projectionMatrix;
+
+ GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);
+ baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
+
+ // Compute the model view matrix for the object rendered with GLKit
+ GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ self.effect.transform.modelviewMatrix = modelViewMatrix;
+
+ // Compute the model view matrix for the object rendered with ES2
+ modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
+
+ _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
+
+ _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0));
+}
+
+
+- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
+{
+ glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glBindVertexArrayOES(_vertexArray);
+
+ // Render the object with GLKit
+ [self.effect prepareToDraw];
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ // Render the object again with ES2
+ glUseProgram(_program);
+
+ glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
+ glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
+ glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] );
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ [self.imgui newFrame];
+
+ // Now do our ImGUI UI
+ DebugHUD_DoInterface( &_hud );
+
+ self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f);
+
+ // Now render Imgui
+ [self.imgui render];
+
+}
+
+#pragma mark - OpenGL ES 2 shader compilation
+
+- (BOOL)loadShaders
+{
+ GLuint vertShader, fragShader;
+ NSString *vertShaderPathname, *fragShaderPathname;
+
+ // Create shader program.
+ _program = glCreateProgram();
+
+ // Create and compile vertex shader.
+ vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
+ if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
+ NSLog(@"Failed to compile vertex shader");
+ return NO;
+ }
+
+ // Create and compile fragment shader.
+ fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
+ if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
+ NSLog(@"Failed to compile fragment shader");
+ return NO;
+ }
+
+ // Attach vertex shader to program.
+ glAttachShader(_program, vertShader);
+
+ // Attach fragment shader to program.
+ glAttachShader(_program, fragShader);
+
+ // Bind attribute locations.
+ // This needs to be done prior to linking.
+ glBindAttribLocation(_program, GLKVertexAttribPosition, "position");
+ glBindAttribLocation(_program, GLKVertexAttribNormal, "normal");
+
+ // Link program.
+ if (![self linkProgram:_program]) {
+ NSLog(@"Failed to link program: %d", _program);
+
+ if (vertShader) {
+ glDeleteShader(vertShader);
+ vertShader = 0;
+ }
+ if (fragShader) {
+ glDeleteShader(fragShader);
+ fragShader = 0;
+ }
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+
+ return NO;
+ }
+
+ // Get uniform locations.
+ uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix");
+ uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix");
+ uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor");
+
+ // Release vertex and fragment shaders.
+ if (vertShader) {
+ glDetachShader(_program, vertShader);
+ glDeleteShader(vertShader);
+ }
+ if (fragShader) {
+ glDetachShader(_program, fragShader);
+ glDeleteShader(fragShader);
+ }
+
+ return YES;
+}
+
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
+{
+ GLint status;
+ const GLchar *source;
+
+ source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
+ if (!source) {
+ NSLog(@"Failed to load vertex shader");
+ return NO;
+ }
+
+ *shader = glCreateShader(type);
+ glShaderSource(*shader, 1, &source, NULL);
+ glCompileShader(*shader);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(*shader, logLength, &logLength, log);
+ NSLog(@"Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
+ if (status == 0) {
+ glDeleteShader(*shader);
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)linkProgram:(GLuint)prog
+{
+ GLint status;
+ glLinkProgram(prog);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program link log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetProgramiv(prog, GL_LINK_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)validateProgram:(GLuint)prog
+{
+ GLint logLength, status;
+
+ glValidateProgram(prog);
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program validate log:\n%s", log);
+ free(log);
+ }
+
+ glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..06b60d8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,77 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@2x~iphone.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@3x~iphone.png",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76~ipad.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76@2x~ipad.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "83.5x83.5",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
new file mode 100644
index 0000000..d728bc3
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
new file mode 100644
index 0000000..f48b799
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
new file mode 100644
index 0000000..67b08b8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
new file mode 100644
index 0000000..ae88e04
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist
new file mode 100644
index 0000000..bc6f548
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Info.plist
@@ -0,0 +1,49 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ org.imgui.example.$(PRODUCT_NAME:rfc1034identifier)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UIStatusBarHidden
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh
new file mode 100644
index 0000000..4000524
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh
@@ -0,0 +1,10 @@
+//
+// Shader.fsh
+// imguiex
+
+varying lowp vec4 colorVarying;
+
+void main()
+{
+ gl_FragColor = colorVarying;
+}
diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh
new file mode 100644
index 0000000..313c3d7
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh
@@ -0,0 +1,25 @@
+//
+// Shader.vsh
+// imguiex
+
+attribute vec4 position;
+attribute vec3 normal;
+
+varying lowp vec4 colorVarying;
+
+uniform vec3 diffuseColor;
+uniform mat4 modelViewProjectionMatrix;
+uniform mat3 normalMatrix;
+
+void main()
+{
+ vec3 eyeNormal = normalize(normalMatrix * normal);
+ vec3 lightPosition = vec3(0.0, 0.0, 1.0);
+
+ float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition)));
+
+ vec3 colorLit = diffuseColor * nDotVP;
+ colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 );
+
+ gl_Position = modelViewProjectionMatrix * position;
+}
diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp
new file mode 100644
index 0000000..c75938a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/debug_hud.cpp
@@ -0,0 +1,45 @@
+//
+// debug_hud.cpp
+// imguiex
+
+#include
+
+#include "debug_hud.h"
+#include "imgui.h"
+
+void DebugHUD_InitDefaults( DebugHUD *hud )
+{
+ hud->show_test_window = true;
+ hud->show_example_window = true;
+ hud->rotation_speed = 15.0f;
+
+ hud->cubeColor1[0] = 0.4f;
+ hud->cubeColor1[1] = 0.4f;
+ hud->cubeColor1[2] = 1.0f;
+ hud->cubeColor1[3] = 1.0f;
+
+ hud->cubeColor2[0] = 1.0f;
+ hud->cubeColor2[1] = 0.4f;
+ hud->cubeColor2[2] = 0.4f;
+ hud->cubeColor2[3] = 1.0f;
+}
+
+void DebugHUD_DoInterface( DebugHUD *hud )
+{
+ if (hud->show_test_window)
+ {
+ ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver );
+ ImGui::ShowTestWindow( &hud->show_test_window );
+ }
+
+ if (hud->show_example_window)
+ {
+ ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver );
+ ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver );
+ ImGui::Begin("Another Window", &hud->show_example_window);
+ ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1);
+ ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2);
+ ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f);
+ ImGui::End();
+ }
+}
diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h
new file mode 100644
index 0000000..17122f5
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/debug_hud.h
@@ -0,0 +1,25 @@
+//
+// debug_hud.h
+// imguiex
+
+#pragma once
+
+typedef struct DebugHUD
+{
+ bool show_test_window;
+ bool show_example_window;
+ float rotation_speed;
+ float cubeColor1[4];
+ float cubeColor2[4];
+} DebugHUD;
+
+#if __cplusplus
+extern "C" {
+#endif
+
+void DebugHUD_InitDefaults( DebugHUD *hud );
+void DebugHUD_DoInterface( DebugHUD *hud );
+
+#if __cplusplus
+}
+#endif
diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png
new file mode 100644
index 0000000..820e4d7
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h
new file mode 100644
index 0000000..9b01dd3
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h
@@ -0,0 +1,22 @@
+// ImGui iOS+OpenGL+Synergy binding
+// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much.
+// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application.
+
+// by Joel Davis (joeld42@gmail.com)
+
+#pragma once
+
+#include
+#include
+
+@interface ImGuiHelper : NSObject
+
+- (id) initWithView: (UIView *)view;
+
+- (void)connectServer: (NSString*)serverName;
+
+- (void)render;
+- (void)newFrame;
+
+@end
diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm
new file mode 100644
index 0000000..893dbf9
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm
@@ -0,0 +1,806 @@
+// ImGui iOS+OpenGL+Synergy binding
+// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much.
+// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application.
+
+// TODO:
+// - Clipboard is not supported.
+
+#import
+#import
+
+#include
+#include
+#include
+#include
+
+#include "imgui_impl_ios.h"
+#include "imgui.h"
+
+#include "uSynergy.h"
+
+// From Carbon HIToolbox/Events.h
+// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247
+enum {
+ kVK_ANSI_A = 0x00,
+ kVK_ANSI_S = 0x01,
+ kVK_ANSI_D = 0x02,
+ kVK_ANSI_F = 0x03,
+ kVK_ANSI_H = 0x04,
+ kVK_ANSI_G = 0x05,
+ kVK_ANSI_Z = 0x06,
+ kVK_ANSI_X = 0x07,
+ kVK_ANSI_C = 0x08,
+ kVK_ANSI_V = 0x09,
+ kVK_ANSI_B = 0x0B,
+ kVK_ANSI_Q = 0x0C,
+ kVK_ANSI_W = 0x0D,
+ kVK_ANSI_E = 0x0E,
+ kVK_ANSI_R = 0x0F,
+ kVK_ANSI_Y = 0x10,
+ kVK_ANSI_T = 0x11,
+ kVK_ANSI_1 = 0x12,
+ kVK_ANSI_2 = 0x13,
+ kVK_ANSI_3 = 0x14,
+ kVK_ANSI_4 = 0x15,
+ kVK_ANSI_6 = 0x16,
+ kVK_ANSI_5 = 0x17,
+ kVK_ANSI_Equal = 0x18,
+ kVK_ANSI_9 = 0x19,
+ kVK_ANSI_7 = 0x1A,
+ kVK_ANSI_Minus = 0x1B,
+ kVK_ANSI_8 = 0x1C,
+ kVK_ANSI_0 = 0x1D,
+ kVK_ANSI_RightBracket = 0x1E,
+ kVK_ANSI_O = 0x1F,
+ kVK_ANSI_U = 0x20,
+ kVK_ANSI_LeftBracket = 0x21,
+ kVK_ANSI_I = 0x22,
+ kVK_ANSI_P = 0x23,
+ kVK_ANSI_L = 0x25,
+ kVK_ANSI_J = 0x26,
+ kVK_ANSI_Quote = 0x27,
+ kVK_ANSI_K = 0x28,
+ kVK_ANSI_Semicolon = 0x29,
+ kVK_ANSI_Backslash = 0x2A,
+ kVK_ANSI_Comma = 0x2B,
+ kVK_ANSI_Slash = 0x2C,
+ kVK_ANSI_N = 0x2D,
+ kVK_ANSI_M = 0x2E,
+ kVK_ANSI_Period = 0x2F,
+ kVK_ANSI_Grave = 0x32,
+ kVK_ANSI_KeypadDecimal = 0x41,
+ kVK_ANSI_KeypadMultiply = 0x43,
+ kVK_ANSI_KeypadPlus = 0x45,
+ kVK_ANSI_KeypadClear = 0x47,
+ kVK_ANSI_KeypadDivide = 0x4B,
+ kVK_ANSI_KeypadEnter = 0x4C,
+ kVK_ANSI_KeypadMinus = 0x4E,
+ kVK_ANSI_KeypadEquals = 0x51,
+ kVK_ANSI_Keypad0 = 0x52,
+ kVK_ANSI_Keypad1 = 0x53,
+ kVK_ANSI_Keypad2 = 0x54,
+ kVK_ANSI_Keypad3 = 0x55,
+ kVK_ANSI_Keypad4 = 0x56,
+ kVK_ANSI_Keypad5 = 0x57,
+ kVK_ANSI_Keypad6 = 0x58,
+ kVK_ANSI_Keypad7 = 0x59,
+ kVK_ANSI_Keypad8 = 0x5B,
+ kVK_ANSI_Keypad9 = 0x5C
+};
+
+/* keycodes for keys that are independent of keyboard layout*/
+enum {
+ kVK_Return = 0x24,
+ kVK_Tab = 0x30,
+ kVK_Space = 0x31,
+ kVK_Delete = 0x33,
+ kVK_Escape = 0x35,
+ kVK_Command = 0x37,
+ kVK_Shift = 0x38,
+ kVK_CapsLock = 0x39,
+ kVK_Option = 0x3A,
+ kVK_Control = 0x3B,
+ kVK_RightShift = 0x3C,
+ kVK_RightOption = 0x3D,
+ kVK_RightControl = 0x3E,
+ kVK_Function = 0x3F,
+ kVK_F17 = 0x40,
+ kVK_VolumeUp = 0x48,
+ kVK_VolumeDown = 0x49,
+ kVK_Mute = 0x4A,
+ kVK_F18 = 0x4F,
+ kVK_F19 = 0x50,
+ kVK_F20 = 0x5A,
+ kVK_F5 = 0x60,
+ kVK_F6 = 0x61,
+ kVK_F7 = 0x62,
+ kVK_F3 = 0x63,
+ kVK_F8 = 0x64,
+ kVK_F9 = 0x65,
+ kVK_F11 = 0x67,
+ kVK_F13 = 0x69,
+ kVK_F16 = 0x6A,
+ kVK_F14 = 0x6B,
+ kVK_F10 = 0x6D,
+ kVK_F12 = 0x6F,
+ kVK_F15 = 0x71,
+ kVK_Help = 0x72,
+ kVK_Home = 0x73,
+ kVK_PageUp = 0x74,
+ kVK_ForwardDelete = 0x75,
+ kVK_F4 = 0x76,
+ kVK_End = 0x77,
+ kVK_F2 = 0x78,
+ kVK_PageDown = 0x79,
+ kVK_F1 = 0x7A,
+ kVK_LeftArrow = 0x7B,
+ kVK_RightArrow = 0x7C,
+ kVK_DownArrow = 0x7D,
+ kVK_UpArrow = 0x7E
+};
+
+static char g_keycodeCharUnshifted[256] = {};
+static char g_keycodeCharShifted[256] = {};
+
+//static double g_Time = 0.0f;
+static bool g_MousePressed[3] = { false, false, false };
+static float g_mouseWheelX = 0.0f;
+static float g_mouseWheelY = 0.0f;
+
+static GLuint g_FontTexture = 0;
+static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0;
+static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0;
+static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0;
+static size_t g_VboSize = 0;
+static unsigned int g_VboHandle = 0, g_VaoHandle = 0;
+static float g_displayScale;
+
+static int usynergy_sockfd;
+static bool g_synergyPtrActive = false;
+static uint16_t g_mousePosX = 0;
+static uint16_t g_mousePosY = 0;
+
+static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data);
+bool ImGui_ImplIOS_CreateDeviceObjects();
+
+static NSString *g_serverName;
+
+uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie)
+{
+ // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since
+ // uSynergy does not support SSL.
+
+ NSLog( @"Connect Func!");
+ struct addrinfo hints, *res;
+
+ // first, load up address structs with getaddrinfo():
+ memset(&hints, 0, sizeof hints);
+ hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
+ hints.ai_socktype = SOCK_STREAM;
+
+ // get server address
+ getaddrinfo([g_serverName UTF8String], "24800", &hints, &res);
+
+ if (!res)
+ {
+ NSLog( @"Could not find server: %@", g_serverName );
+ return USYNERGY_FALSE;
+ }
+
+ // make a socket:
+ usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+
+ // connect it to the address and port we passed in to getaddrinfo():
+ int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen);
+ if (!ret) {
+ NSLog( @"Connect succeeded...");
+ } else {
+ NSLog( @"Connect failed, %d", ret );
+ }
+
+
+ return USYNERGY_TRUE;
+}
+
+uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length)
+{
+// NSLog( @"Send Func" );
+ send( usynergy_sockfd, buffer, length, 0 );
+
+ return USYNERGY_TRUE;
+}
+
+uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength)
+{
+ *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 );
+
+ return USYNERGY_TRUE;
+}
+
+void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs)
+{
+ usleep( timeMs * 1000 );
+}
+
+uint32_t ImGui_GetTimeFunc()
+{
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+
+ return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000);
+}
+
+void ImGui_TraceFunc(uSynergyCookie cookie, const char *text)
+{
+ puts(text);
+}
+
+void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active)
+{
+ g_synergyPtrActive = active;
+// printf( "Synergy: screen activate %s\n", active?"YES":"NO" );
+}
+
+void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY,
+ uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle)
+{
+// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY );
+ uSynergyContext *ctx = (uSynergyContext*)cookie;
+ g_mousePosX = x;
+ g_mousePosY = y;
+ g_mouseWheelX = wheelX;
+ g_mouseWheelY = wheelY;
+ g_MousePressed[0] = buttonLeft;
+ g_MousePressed[1] = buttonMiddle;
+ g_MousePressed[2] = buttonRight;
+
+ ctx->m_mouseWheelX = 0;
+ ctx->m_mouseWheelY = 0;
+}
+
+void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key,
+ uint16_t modifiers, uSynergyBool down, uSynergyBool repeat)
+{
+ int scanCode = key-1;
+// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false");
+ ImGuiIO& io = ImGui::GetIO();
+ io.KeysDown[key] = down;
+ io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT);
+ io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL);
+ io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT);
+ io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN);
+
+ // Add this as keyboard input
+ if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL))
+ {
+ // If this key maps to a character input, apply it
+ int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode];
+ io.AddInputCharacter((unsigned short)charForKeycode);
+ }
+
+}
+
+void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY)
+{
+ printf("Synergy: joystick callback TODO\n");
+}
+
+void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size)
+{
+ printf("Synergy: clipboard callback TODO\n" );
+}
+
+@interface ImGuiHelper ()
+{
+ BOOL _mouseDown;
+ BOOL _mouseTapped;
+ CGPoint _touchPos;
+
+ uSynergyContext _synergyCtx;
+ dispatch_queue_t _synergyQueue;
+}
+@property (nonatomic, weak) UIView *view;
+@property (nonatomic, strong) NSString *serverName;
+
+@end
+
+@implementation ImGuiHelper
+
+- (id) initWithView: (UIView *)view
+{
+ self = [super init];
+ if (self)
+ {
+ self.view = view;
+
+ [self setupImGuiHooks];
+ }
+ return self;
+}
+
+- (void)setupKeymaps
+{
+ // The keyboard mapping is a big headache. I tried for a while to find a better way to do this,
+ // but this was the best I could come up with. There are some device independent API's available
+ // to convert scan codes to unicode characters, but these are only available on mac and not
+ // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do
+ // this or any way to get the character codes out of usynergy.
+ g_keycodeCharUnshifted[ kVK_ANSI_A ]='a';
+ g_keycodeCharUnshifted[ kVK_ANSI_S ]='s';
+ g_keycodeCharUnshifted[ kVK_ANSI_D ]='d';
+ g_keycodeCharUnshifted[ kVK_ANSI_F ]='f';
+ g_keycodeCharUnshifted[ kVK_ANSI_H ]='h';
+ g_keycodeCharUnshifted[ kVK_ANSI_G ]='g';
+ g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z';
+ g_keycodeCharUnshifted[ kVK_ANSI_X ]='x';
+ g_keycodeCharUnshifted[ kVK_ANSI_C ]='c';
+ g_keycodeCharUnshifted[ kVK_ANSI_V ]='v';
+ g_keycodeCharUnshifted[ kVK_ANSI_B ]='b';
+ g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q';
+ g_keycodeCharUnshifted[ kVK_ANSI_W ]='w';
+ g_keycodeCharUnshifted[ kVK_ANSI_E ]='e';
+ g_keycodeCharUnshifted[ kVK_ANSI_R ]='r';
+ g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y';
+ g_keycodeCharUnshifted[ kVK_ANSI_T ]='t';
+ g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1';
+ g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2';
+ g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3';
+ g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4';
+ g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6';
+ g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5';
+ g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='=';
+ g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9';
+ g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7';
+ g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-';
+ g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8';
+ g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0';
+ g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']';
+ g_keycodeCharUnshifted[ kVK_ANSI_O ]='o';
+ g_keycodeCharUnshifted[ kVK_ANSI_U ]='u';
+ g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='[';
+ g_keycodeCharUnshifted[ kVK_ANSI_I ]='i';
+ g_keycodeCharUnshifted[ kVK_ANSI_P ]='p';
+ g_keycodeCharUnshifted[ kVK_ANSI_L ]='l';
+ g_keycodeCharUnshifted[ kVK_ANSI_J ]='j';
+ g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\'';
+ g_keycodeCharUnshifted[ kVK_ANSI_K ]='k';
+ g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';';
+ g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\';
+ g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=',';
+ g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/';
+ g_keycodeCharUnshifted[ kVK_ANSI_N ]='n';
+ g_keycodeCharUnshifted[ kVK_ANSI_M ]='m';
+ g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.';
+ g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='=';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9';
+ g_keycodeCharUnshifted[ kVK_Space ]=' ';
+
+ g_keycodeCharShifted[ kVK_ANSI_A ]='A';
+ g_keycodeCharShifted[ kVK_ANSI_S ]='S';
+ g_keycodeCharShifted[ kVK_ANSI_D ]='D';
+ g_keycodeCharShifted[ kVK_ANSI_F ]='F';
+ g_keycodeCharShifted[ kVK_ANSI_H ]='H';
+ g_keycodeCharShifted[ kVK_ANSI_G ]='G';
+ g_keycodeCharShifted[ kVK_ANSI_Z ]='Z';
+ g_keycodeCharShifted[ kVK_ANSI_X ]='X';
+ g_keycodeCharShifted[ kVK_ANSI_C ]='C';
+ g_keycodeCharShifted[ kVK_ANSI_V ]='V';
+ g_keycodeCharShifted[ kVK_ANSI_B ]='B';
+ g_keycodeCharShifted[ kVK_ANSI_Q ]='Q';
+ g_keycodeCharShifted[ kVK_ANSI_W ]='W';
+ g_keycodeCharShifted[ kVK_ANSI_E ]='E';
+ g_keycodeCharShifted[ kVK_ANSI_R ]='R';
+ g_keycodeCharShifted[ kVK_ANSI_Y ]='Y';
+ g_keycodeCharShifted[ kVK_ANSI_T ]='T';
+ g_keycodeCharShifted[ kVK_ANSI_1 ]='!';
+ g_keycodeCharShifted[ kVK_ANSI_2 ]='@';
+ g_keycodeCharShifted[ kVK_ANSI_3 ]='#';
+ g_keycodeCharShifted[ kVK_ANSI_4 ]='$';
+ g_keycodeCharShifted[ kVK_ANSI_6 ]='^';
+ g_keycodeCharShifted[ kVK_ANSI_5 ]='%';
+ g_keycodeCharShifted[ kVK_ANSI_Equal ]='+';
+ g_keycodeCharShifted[ kVK_ANSI_9 ]='(';
+ g_keycodeCharShifted[ kVK_ANSI_7 ]='&';
+ g_keycodeCharShifted[ kVK_ANSI_Minus ]='_';
+ g_keycodeCharShifted[ kVK_ANSI_8 ]='*';
+ g_keycodeCharShifted[ kVK_ANSI_0 ]=')';
+ g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}';
+ g_keycodeCharShifted[ kVK_ANSI_O ]='O';
+ g_keycodeCharShifted[ kVK_ANSI_U ]='U';
+ g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{';
+ g_keycodeCharShifted[ kVK_ANSI_I ]='I';
+ g_keycodeCharShifted[ kVK_ANSI_P ]='P';
+ g_keycodeCharShifted[ kVK_ANSI_L ]='L';
+ g_keycodeCharShifted[ kVK_ANSI_J ]='J';
+ g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"';
+ g_keycodeCharShifted[ kVK_ANSI_K ]='K';
+ g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':';
+ g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|';
+ g_keycodeCharShifted[ kVK_ANSI_Comma ]='<';
+ g_keycodeCharShifted[ kVK_ANSI_Slash ]='?';
+ g_keycodeCharShifted[ kVK_ANSI_N ]='N';
+ g_keycodeCharShifted[ kVK_ANSI_M ]='M';
+ g_keycodeCharShifted[ kVK_ANSI_Period ]='>';
+ g_keycodeCharShifted[ kVK_ANSI_Grave ]='~';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='=';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9';
+ g_keycodeCharShifted[ kVK_Space ]=' ';
+}
+
+- (void)setupImGuiHooks
+{
+ ImGuiIO &io = ImGui::GetIO();
+
+ [self setupKeymaps];
+
+ // Account for retina display for glScissor
+ g_displayScale = [[UIScreen mainScreen] scale];
+
+ ImGuiStyle &style = ImGui::GetStyle();
+ style.TouchExtraPadding = ImVec2( 4.0, 4.0 );
+
+ io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists;
+
+ UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ];
+ [self.view addGestureRecognizer:panRecognizer];
+
+ UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)];
+ [self.view addGestureRecognizer:tapRecoginzer];
+
+ // Fill out the Synergy key map
+ // (for some reason synergy scan codes are off by 1)
+ io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1;
+ io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1;
+ io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1;
+ io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1;
+ io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1;
+ io.KeyMap[ImGuiKey_Home] = kVK_Home+1;
+ io.KeyMap[ImGuiKey_End] = kVK_End+1;
+ io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1;
+ io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1;
+ io.KeyMap[ImGuiKey_Enter] = kVK_Return+1;
+ io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1;
+ io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1;
+ io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1;
+ io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1;
+ io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1;
+ io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1;
+ io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1;
+}
+
+- (void)connectServer: (NSString*)serverName
+{
+ self.serverName = serverName;
+ g_serverName = serverName;
+
+ // Init synergy
+ NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey];
+
+ uSynergyInit( &_synergyCtx );
+ _synergyCtx.m_clientName = strdup( [bundleName UTF8String] );
+ _synergyCtx.m_clientWidth = self.view.bounds.size.width;
+ _synergyCtx.m_clientHeight = self.view.bounds.size.height;
+
+ _synergyCtx.m_connectFunc = ImGui_ConnectFunc;
+ _synergyCtx.m_sendFunc = ImGui_SendFunc;
+ _synergyCtx.m_receiveFunc = ImGui_RecvFunc;
+ _synergyCtx.m_sleepFunc = ImGui_SleepFunc;
+ _synergyCtx.m_traceFunc = ImGui_TraceFunc;
+ _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc;
+
+ _synergyCtx.m_traceFunc = ImGui_TraceFunc;
+ _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback;
+ _synergyCtx.m_mouseCallback = ImGui_MouseCallback;
+ _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback;
+
+ _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx;
+
+ // Create a background thread for synergy
+ _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL );
+ dispatch_async( _synergyQueue, ^{
+ while (1) {
+ uSynergyUpdate( &_synergyCtx );
+ }
+ });
+}
+
+
+- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer
+{
+
+ if ((recognizer.state == UIGestureRecognizerStateBegan) ||
+ (recognizer.state == UIGestureRecognizerStateChanged))
+ {
+ _mouseDown = YES;
+ _touchPos = [recognizer locationInView:self.view];
+ }
+ else
+ {
+ _mouseDown = NO;
+ _touchPos = CGPointMake( -1, -1 );
+ }
+}
+
+- (void)viewDidTap: (UITapGestureRecognizer*)recognizer
+{
+ _touchPos = [recognizer locationInView:self.view];
+ _mouseTapped = YES;
+}
+
+- (void)render
+{
+ ImGui::Render();
+}
+
+- (void)newFrame
+{
+ ImGuiIO& io = ImGui::GetIO();
+ ImGuiStyle &style = ImGui::GetStyle();
+
+ if (!g_FontTexture)
+ {
+ ImGui_ImplIOS_CreateDeviceObjects();
+ }
+
+ io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height );
+
+ io.MouseDrawCursor = g_synergyPtrActive;
+ if (g_synergyPtrActive)
+ {
+ style.TouchExtraPadding = ImVec2( 0.0, 0.0 );
+ io.MousePos = ImVec2( g_mousePosX, g_mousePosY );
+ for (int i=0; i < 3; i++)
+ {
+ io.MouseDown[i] = g_MousePressed[i];
+ }
+
+ // This is an arbitrary scaling factor that works for me. Not sure what units these
+ // mousewheel values from synergy are supposed to be in
+ io.MouseWheel = g_mouseWheelY / 500.0;
+ }
+ else
+ {
+ // Synergy not active, use touch events
+ style.TouchExtraPadding = ImVec2( 4.0, 4.0 );
+ io.MousePos = ImVec2(_touchPos.x, _touchPos.y );
+ if ((_mouseDown) || (_mouseTapped))
+ {
+ io.MouseDown[0] = true;
+ _mouseTapped = NO;
+ }
+ else
+ {
+ io.MouseDown[0] = false;
+ }
+ }
+
+ ImGui::NewFrame();
+}
+@end
+
+// 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)
+// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES
+static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data)
+{
+ // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled
+ GLint last_program, last_texture;
+ glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+ glEnable(GL_BLEND);
+ glBlendEquation(GL_FUNC_ADD);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_SCISSOR_TEST);
+ glActiveTexture(GL_TEXTURE0);
+
+ // Setup orthographic projection matrix
+ const float width = ImGui::GetIO().DisplaySize.x;
+ const float height = ImGui::GetIO().DisplaySize.y;
+ const float ortho_projection[4][4] =
+ {
+ { 2.0f/width, 0.0f, 0.0f, 0.0f },
+ { 0.0f, 2.0f/-height, 0.0f, 0.0f },
+ { 0.0f, 0.0f, -1.0f, 0.0f },
+ { -1.0f, 1.0f, 0.0f, 1.0f },
+ };
+ glUseProgram(g_ShaderHandle);
+ glUniform1i(g_AttribLocationTex, 0);
+ glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
+ glBindVertexArray(g_VaoHandle);
+
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
+ {
+ ImDrawList* cmd_list = draw_data->CmdLists[n];
+ ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front();
+
+ glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
+ const int needed_vtx_size = cmd_list->VtxBuffer.Size * sizeof(ImDrawVert);
+ if (g_VboSize < needed_vtx_size)
+ {
+ // Grow our buffer if needed
+ g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert);
+ glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW);
+ }
+
+ unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
+ if (!vtx_data)
+ continue;
+ memcpy(vtx_data, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
+ {
+ const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
+ if (pcmd->UserCallback)
+ {
+ pcmd->UserCallback(cmd_list, pcmd);
+ }
+ else
+ {
+ glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId);
+ glScissor((int)(pcmd->ClipRect.x * g_displayScale),
+ (int)((height - pcmd->ClipRect.w) * g_displayScale),
+ (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale),
+ (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale));
+ glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer );
+ }
+ idx_buffer += pcmd->ElemCount;
+ }
+ }
+
+ // Restore modified state
+ glBindVertexArray(0);
+ glBindBuffer( GL_ARRAY_BUFFER, 0);
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_DEPTH_TEST);
+ glUseProgram(last_program);
+ glDisable(GL_SCISSOR_TEST);
+ glBindTexture(GL_TEXTURE_2D, last_texture);
+}
+
+void ImGui_ImplIOS_CreateFontsTexture()
+{
+ // Build texture atlas
+ ImGuiIO& io = ImGui::GetIO();
+ unsigned char* pixels;
+ int width, height;
+ io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader.
+
+ // Upload texture to graphics system
+ GLint last_texture;
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+ glGenTextures(1, &g_FontTexture);
+ glBindTexture(GL_TEXTURE_2D, g_FontTexture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+
+ // Store our identifier
+ io.Fonts->TexID = (void *)(intptr_t)g_FontTexture;
+
+ // Restore state
+ glBindTexture(GL_TEXTURE_2D, last_texture);
+}
+
+bool ImGui_ImplIOS_CreateDeviceObjects()
+{
+ const GLchar *vertex_shader =
+ "uniform mat4 ProjMtx;\n"
+ "attribute highp vec2 Position;\n"
+ "attribute highp vec2 UV;\n"
+ "attribute highp vec4 Color;\n"
+ "varying vec2 Frag_UV;\n"
+ "varying vec4 Frag_Color;\n"
+ "void main()\n"
+ "{\n"
+ " Frag_UV = UV;\n"
+ " Frag_Color = Color;\n"
+ " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
+ "}\n";
+
+ const GLchar* fragment_shader =
+ "uniform sampler2D Texture;\n"
+ "varying highp vec2 Frag_UV;\n"
+ "varying highp vec4 Frag_Color;\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n"
+ "}\n";
+
+ g_ShaderHandle = glCreateProgram();
+ g_VertHandle = glCreateShader(GL_VERTEX_SHADER);
+ g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER);
+ glShaderSource(g_VertHandle, 1, &vertex_shader, 0);
+ glShaderSource(g_FragHandle, 1, &fragment_shader, 0);
+ glCompileShader(g_VertHandle);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log);
+ NSLog(@"VERTEX Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glCompileShader(g_FragHandle);
+
+#if defined(DEBUG)
+ glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log);
+ NSLog(@"FRAGMENT Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glAttachShader(g_ShaderHandle, g_VertHandle);
+ glAttachShader(g_ShaderHandle, g_FragHandle);
+ glLinkProgram(g_ShaderHandle);
+
+ g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture");
+ g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx");
+ g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position");
+ g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV");
+ g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color");
+
+ glGenBuffers(1, &g_VboHandle);
+
+ glGenVertexArrays(1, &g_VaoHandle);
+ glBindVertexArray(g_VaoHandle);
+ glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
+ glEnableVertexAttribArray(g_AttribLocationPosition);
+ glEnableVertexAttribArray(g_AttribLocationUV);
+ glEnableVertexAttribArray(g_AttribLocationColor);
+
+#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
+ glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos));
+ glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv));
+ glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col));
+#undef OFFSETOF
+ glBindVertexArray(0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ ImGui_ImplIOS_CreateFontsTexture();
+
+ return true;
+}
diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m
new file mode 100644
index 0000000..faba099
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/main.m
@@ -0,0 +1,13 @@
+//
+// main.m
+// imguiex
+//
+
+#import
+#import "AppDelegate.h"
+
+int main(int argc, char * argv[]) {
+ @autoreleasepool {
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+ }
+}
diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h
new file mode 100644
index 0000000..33d199b
--- /dev/null
+++ b/examples/apple_example/imguiex-osx/AppDelegate.h
@@ -0,0 +1,15 @@
+//
+// AppDelegate.h
+// imguiex-osx
+//
+// Created by James Chen on 4/5/16.
+// Copyright © 2016 Joel Davis. All rights reserved.
+//
+
+#import
+
+@interface AppDelegate : NSObject
+
+
+@end
+
diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m
new file mode 100644
index 0000000..59e877b
--- /dev/null
+++ b/examples/apple_example/imguiex-osx/AppDelegate.m
@@ -0,0 +1,26 @@
+//
+// AppDelegate.m
+// imguiex-osx
+//
+// Created by James Chen on 4/5/16.
+// Copyright © 2016 Joel Davis. All rights reserved.
+//
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@property (weak) IBOutlet NSWindow *window;
+@end
+
+@implementation AppDelegate
+
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
+ // Insert code here to initialize your application
+}
+
+- (void)applicationWillTerminate:(NSNotification *)aNotification {
+ // Insert code here to tear down your application
+}
+
+@end
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore
new file mode 100644
index 0000000..8feda89
--- /dev/null
+++ b/examples/apple_example/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+imguiex.xcodeproj/project.xcworkspace/
+imguiex.xcodeproj/xcuserdata/
\ No newline at end of file
diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md
new file mode 100644
index 0000000..339f6bf
--- /dev/null
+++ b/examples/apple_example/README.md
@@ -0,0 +1,41 @@
+# iOS / OSX example
+
+## Introduction
+
+This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device.
+
+It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy.
+
+Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active.
+
+## How to Use on iOS
+
+* In Synergy, go to Preferences, and uncheck "Use SSL encryption"
+* Run the example app.
+* Tap the "servername" button in the corner
+* Enter the name or the IP of your synergy host
+* If you had previously connected to a server, you may need to kill and re-start the app.
+
+## How to Build on OSX
+
+* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh)
+* Run the command: `brew install glfw3`
+* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme
+* Click `Run` button
+
+## Notes and TODOs
+
+Things that would be nice but I didn't get around to doing:
+
+* iOS software keyboard not supported for text inputs
+* iOS hardware (bluetooth) keyboards not supported
+* Graceful disconnect/reconnect from uSynergy.
+* Copy/Paste not well-supported
+
+## C++ on iOS / OSX
+
+ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension.
+
+Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer.
+
+In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly.
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h
new file mode 100644
index 0000000..82f1542
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.h
@@ -0,0 +1,13 @@
+//
+// AppDelegate.h
+// imguiex
+
+#import
+
+@interface AppDelegate : UIResponder
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m
new file mode 100644
index 0000000..ab83101
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.m
@@ -0,0 +1,41 @@
+//
+// AppDelegate.m
+// imguiex
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Override point for customization after application launch.
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
new file mode 100644
index 0000000..5717c00
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..90dfb2e
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h
new file mode 100644
index 0000000..3323cfd
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.h
@@ -0,0 +1,12 @@
+//
+// GameViewController.h
+// imguiex
+
+// This is the OpenGL Example template from XCode, modified to support ImGui
+
+#import
+#import
+
+@interface GameViewController : GLKViewController
+
+@end
diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m
new file mode 100644
index 0000000..e902f7a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.m
@@ -0,0 +1,481 @@
+//
+// GameViewController.m
+// imguiex
+//
+#import "GameViewController.h"
+#import
+
+#import "imgui_impl_ios.h"
+#import "debug_hud.h"
+
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
+
+#define SERVERNAME_KEY @"ServerName"
+
+#define SERVERNAME_ALERT_TAG (10)
+
+// Uniform index.
+enum
+{
+ UNIFORM_MODELVIEWPROJECTION_MATRIX,
+ UNIFORM_NORMAL_MATRIX,
+ UNIFORM_DIFFUSE_COLOR,
+
+ NUM_UNIFORMS
+};
+GLint uniforms[NUM_UNIFORMS];
+
+// Attribute index.
+enum
+{
+ ATTRIB_VERTEX,
+ ATTRIB_NORMAL,
+ NUM_ATTRIBUTES
+};
+
+GLfloat gCubeVertexData[216] =
+{
+ // Data layout for each line below is:
+ // positionX, positionY, positionZ, normalX, normalY, normalZ,
+ 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+
+ 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+
+ -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+
+ -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+
+ 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+
+ 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f
+};
+
+@interface GameViewController ()
+{
+ GLuint _program;
+
+ GLKMatrix4 _modelViewProjectionMatrix;
+ GLKMatrix3 _normalMatrix;
+ float _rotation;
+
+ GLuint _vertexArray;
+ GLuint _vertexBuffer;
+
+ DebugHUD _hud;
+}
+@property (strong, nonatomic) EAGLContext *context;
+@property (strong, nonatomic) GLKBaseEffect *effect;
+@property (strong, nonatomic) ImGuiHelper *imgui;
+@property (weak, nonatomic) IBOutlet UIButton *btnServername;
+
+@property (strong, nonatomic) NSString *serverName;
+
+- (IBAction)onServernameTapped:(id)sender;
+
+- (void)setupGL;
+- (void)tearDownGL;
+
+- (BOOL)loadShaders;
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file;
+- (BOOL)linkProgram:(GLuint)prog;
+- (BOOL)validateProgram:(GLuint)prog;
+@end
+
+@implementation GameViewController
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+
+ if (!self.context) {
+ NSLog(@"Failed to create ES context");
+ }
+
+ GLKView *view = (GLKView *)self.view;
+ view.context = self.context;
+ view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
+
+ [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
+
+ [self setupGL];
+
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ];
+ self.imgui = [[ImGuiHelper alloc] initWithView:self.view ];
+ if (self.serverName)
+ {
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+ [self.imgui connectServer: self.serverName ];
+ }
+
+ DebugHUD_InitDefaults( &_hud );
+}
+
+- (void)dealloc
+{
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+
+ if ([self isViewLoaded] && ([[self view] window] == nil)) {
+ self.view = nil;
+
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+ self.context = nil;
+ }
+
+ // Dispose of any resources that can be recreated.
+}
+
+
+- (BOOL)prefersStatusBarHidden {
+ return YES;
+}
+
+- (IBAction)onServernameTapped:(id)sender
+{
+ UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ];
+ alert.alertViewStyle = UIAlertViewStylePlainTextInput;
+ alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to
+ [alert show];
+}
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG))
+ {
+ // This is really janky. I usually just hardcode the servername since I'm building it anyway.
+ // If you want to properly handle updating the server, you'll want to tear down and recreate
+ // the usynergy stuff in connectServer
+ BOOL serverNameWasSet = self.serverName.length > 0;
+ NSString *serverName = [[alertView textFieldAtIndex:0] text];
+
+ if ([serverName length] > 0) {
+ self.serverName = serverName;
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ [userDefaults setObject:serverName forKey:SERVERNAME_KEY ];
+ [userDefaults synchronize];
+
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+
+ // If we hadn't previously connected, try now
+ if (!serverNameWasSet) {
+ [self.imgui connectServer:self.serverName];
+ }
+ else
+ {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated"
+ message:@"Restart the app to connect the server"
+ delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
+ [alert show];
+ }
+ }
+ }
+}
+
+- (void)setupGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ [self loadShaders];
+
+ self.effect = [[GLKBaseEffect alloc] init];
+ self.effect.light0.enabled = GL_TRUE;
+ self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f);
+
+ glEnable(GL_DEPTH_TEST);
+
+ glGenVertexArraysOES(1, &_vertexArray);
+ glBindVertexArrayOES(_vertexArray);
+
+ glGenBuffers(1, &_vertexBuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);
+
+ glEnableVertexAttribArray(GLKVertexAttribPosition);
+ glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
+ glEnableVertexAttribArray(GLKVertexAttribNormal);
+ glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
+
+ glBindVertexArrayOES(0);
+
+
+}
+
+- (void)tearDownGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ glDeleteBuffers(1, &_vertexBuffer);
+ glDeleteVertexArraysOES(1, &_vertexArray);
+
+ self.effect = nil;
+
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+}
+
+#pragma mark - GLKView and GLKViewController delegate methods
+
+- (void)update
+{
+ float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height);
+ GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
+
+ self.effect.transform.projectionMatrix = projectionMatrix;
+
+ GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);
+ baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
+
+ // Compute the model view matrix for the object rendered with GLKit
+ GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ self.effect.transform.modelviewMatrix = modelViewMatrix;
+
+ // Compute the model view matrix for the object rendered with ES2
+ modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
+
+ _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
+
+ _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0));
+}
+
+
+- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
+{
+ glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glBindVertexArrayOES(_vertexArray);
+
+ // Render the object with GLKit
+ [self.effect prepareToDraw];
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ // Render the object again with ES2
+ glUseProgram(_program);
+
+ glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
+ glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
+ glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] );
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ [self.imgui newFrame];
+
+ // Now do our ImGUI UI
+ DebugHUD_DoInterface( &_hud );
+
+ self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f);
+
+ // Now render Imgui
+ [self.imgui render];
+
+}
+
+#pragma mark - OpenGL ES 2 shader compilation
+
+- (BOOL)loadShaders
+{
+ GLuint vertShader, fragShader;
+ NSString *vertShaderPathname, *fragShaderPathname;
+
+ // Create shader program.
+ _program = glCreateProgram();
+
+ // Create and compile vertex shader.
+ vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
+ if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
+ NSLog(@"Failed to compile vertex shader");
+ return NO;
+ }
+
+ // Create and compile fragment shader.
+ fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
+ if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
+ NSLog(@"Failed to compile fragment shader");
+ return NO;
+ }
+
+ // Attach vertex shader to program.
+ glAttachShader(_program, vertShader);
+
+ // Attach fragment shader to program.
+ glAttachShader(_program, fragShader);
+
+ // Bind attribute locations.
+ // This needs to be done prior to linking.
+ glBindAttribLocation(_program, GLKVertexAttribPosition, "position");
+ glBindAttribLocation(_program, GLKVertexAttribNormal, "normal");
+
+ // Link program.
+ if (![self linkProgram:_program]) {
+ NSLog(@"Failed to link program: %d", _program);
+
+ if (vertShader) {
+ glDeleteShader(vertShader);
+ vertShader = 0;
+ }
+ if (fragShader) {
+ glDeleteShader(fragShader);
+ fragShader = 0;
+ }
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+
+ return NO;
+ }
+
+ // Get uniform locations.
+ uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix");
+ uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix");
+ uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor");
+
+ // Release vertex and fragment shaders.
+ if (vertShader) {
+ glDetachShader(_program, vertShader);
+ glDeleteShader(vertShader);
+ }
+ if (fragShader) {
+ glDetachShader(_program, fragShader);
+ glDeleteShader(fragShader);
+ }
+
+ return YES;
+}
+
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
+{
+ GLint status;
+ const GLchar *source;
+
+ source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
+ if (!source) {
+ NSLog(@"Failed to load vertex shader");
+ return NO;
+ }
+
+ *shader = glCreateShader(type);
+ glShaderSource(*shader, 1, &source, NULL);
+ glCompileShader(*shader);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(*shader, logLength, &logLength, log);
+ NSLog(@"Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
+ if (status == 0) {
+ glDeleteShader(*shader);
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)linkProgram:(GLuint)prog
+{
+ GLint status;
+ glLinkProgram(prog);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program link log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetProgramiv(prog, GL_LINK_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)validateProgram:(GLuint)prog
+{
+ GLint logLength, status;
+
+ glValidateProgram(prog);
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program validate log:\n%s", log);
+ free(log);
+ }
+
+ glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..06b60d8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,77 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@2x~iphone.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@3x~iphone.png",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76~ipad.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76@2x~ipad.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "83.5x83.5",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
new file mode 100644
index 0000000..d728bc3
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
new file mode 100644
index 0000000..f48b799
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
new file mode 100644
index 0000000..67b08b8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
new file mode 100644
index 0000000..ae88e04
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist
new file mode 100644
index 0000000..bc6f548
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Info.plist
@@ -0,0 +1,49 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ org.imgui.example.$(PRODUCT_NAME:rfc1034identifier)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UIStatusBarHidden
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh
new file mode 100644
index 0000000..4000524
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh
@@ -0,0 +1,10 @@
+//
+// Shader.fsh
+// imguiex
+
+varying lowp vec4 colorVarying;
+
+void main()
+{
+ gl_FragColor = colorVarying;
+}
diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh
new file mode 100644
index 0000000..313c3d7
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh
@@ -0,0 +1,25 @@
+//
+// Shader.vsh
+// imguiex
+
+attribute vec4 position;
+attribute vec3 normal;
+
+varying lowp vec4 colorVarying;
+
+uniform vec3 diffuseColor;
+uniform mat4 modelViewProjectionMatrix;
+uniform mat3 normalMatrix;
+
+void main()
+{
+ vec3 eyeNormal = normalize(normalMatrix * normal);
+ vec3 lightPosition = vec3(0.0, 0.0, 1.0);
+
+ float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition)));
+
+ vec3 colorLit = diffuseColor * nDotVP;
+ colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 );
+
+ gl_Position = modelViewProjectionMatrix * position;
+}
diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp
new file mode 100644
index 0000000..c75938a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/debug_hud.cpp
@@ -0,0 +1,45 @@
+//
+// debug_hud.cpp
+// imguiex
+
+#include
+
+#include "debug_hud.h"
+#include "imgui.h"
+
+void DebugHUD_InitDefaults( DebugHUD *hud )
+{
+ hud->show_test_window = true;
+ hud->show_example_window = true;
+ hud->rotation_speed = 15.0f;
+
+ hud->cubeColor1[0] = 0.4f;
+ hud->cubeColor1[1] = 0.4f;
+ hud->cubeColor1[2] = 1.0f;
+ hud->cubeColor1[3] = 1.0f;
+
+ hud->cubeColor2[0] = 1.0f;
+ hud->cubeColor2[1] = 0.4f;
+ hud->cubeColor2[2] = 0.4f;
+ hud->cubeColor2[3] = 1.0f;
+}
+
+void DebugHUD_DoInterface( DebugHUD *hud )
+{
+ if (hud->show_test_window)
+ {
+ ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver );
+ ImGui::ShowTestWindow( &hud->show_test_window );
+ }
+
+ if (hud->show_example_window)
+ {
+ ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver );
+ ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver );
+ ImGui::Begin("Another Window", &hud->show_example_window);
+ ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1);
+ ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2);
+ ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f);
+ ImGui::End();
+ }
+}
diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h
new file mode 100644
index 0000000..17122f5
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/debug_hud.h
@@ -0,0 +1,25 @@
+//
+// debug_hud.h
+// imguiex
+
+#pragma once
+
+typedef struct DebugHUD
+{
+ bool show_test_window;
+ bool show_example_window;
+ float rotation_speed;
+ float cubeColor1[4];
+ float cubeColor2[4];
+} DebugHUD;
+
+#if __cplusplus
+extern "C" {
+#endif
+
+void DebugHUD_InitDefaults( DebugHUD *hud );
+void DebugHUD_DoInterface( DebugHUD *hud );
+
+#if __cplusplus
+}
+#endif
diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png
new file mode 100644
index 0000000..820e4d7
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h
new file mode 100644
index 0000000..9b01dd3
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h
@@ -0,0 +1,22 @@
+// ImGui iOS+OpenGL+Synergy binding
+// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much.
+// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application.
+
+// by Joel Davis (joeld42@gmail.com)
+
+#pragma once
+
+#include
+#include
+
+@interface ImGuiHelper : NSObject
+
+- (id) initWithView: (UIView *)view;
+
+- (void)connectServer: (NSString*)serverName;
+
+- (void)render;
+- (void)newFrame;
+
+@end
diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm
new file mode 100644
index 0000000..893dbf9
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm
@@ -0,0 +1,806 @@
+// ImGui iOS+OpenGL+Synergy binding
+// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much.
+// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application.
+
+// TODO:
+// - Clipboard is not supported.
+
+#import
+#import
+
+#include
+#include
+#include
+#include
+
+#include "imgui_impl_ios.h"
+#include "imgui.h"
+
+#include "uSynergy.h"
+
+// From Carbon HIToolbox/Events.h
+// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247
+enum {
+ kVK_ANSI_A = 0x00,
+ kVK_ANSI_S = 0x01,
+ kVK_ANSI_D = 0x02,
+ kVK_ANSI_F = 0x03,
+ kVK_ANSI_H = 0x04,
+ kVK_ANSI_G = 0x05,
+ kVK_ANSI_Z = 0x06,
+ kVK_ANSI_X = 0x07,
+ kVK_ANSI_C = 0x08,
+ kVK_ANSI_V = 0x09,
+ kVK_ANSI_B = 0x0B,
+ kVK_ANSI_Q = 0x0C,
+ kVK_ANSI_W = 0x0D,
+ kVK_ANSI_E = 0x0E,
+ kVK_ANSI_R = 0x0F,
+ kVK_ANSI_Y = 0x10,
+ kVK_ANSI_T = 0x11,
+ kVK_ANSI_1 = 0x12,
+ kVK_ANSI_2 = 0x13,
+ kVK_ANSI_3 = 0x14,
+ kVK_ANSI_4 = 0x15,
+ kVK_ANSI_6 = 0x16,
+ kVK_ANSI_5 = 0x17,
+ kVK_ANSI_Equal = 0x18,
+ kVK_ANSI_9 = 0x19,
+ kVK_ANSI_7 = 0x1A,
+ kVK_ANSI_Minus = 0x1B,
+ kVK_ANSI_8 = 0x1C,
+ kVK_ANSI_0 = 0x1D,
+ kVK_ANSI_RightBracket = 0x1E,
+ kVK_ANSI_O = 0x1F,
+ kVK_ANSI_U = 0x20,
+ kVK_ANSI_LeftBracket = 0x21,
+ kVK_ANSI_I = 0x22,
+ kVK_ANSI_P = 0x23,
+ kVK_ANSI_L = 0x25,
+ kVK_ANSI_J = 0x26,
+ kVK_ANSI_Quote = 0x27,
+ kVK_ANSI_K = 0x28,
+ kVK_ANSI_Semicolon = 0x29,
+ kVK_ANSI_Backslash = 0x2A,
+ kVK_ANSI_Comma = 0x2B,
+ kVK_ANSI_Slash = 0x2C,
+ kVK_ANSI_N = 0x2D,
+ kVK_ANSI_M = 0x2E,
+ kVK_ANSI_Period = 0x2F,
+ kVK_ANSI_Grave = 0x32,
+ kVK_ANSI_KeypadDecimal = 0x41,
+ kVK_ANSI_KeypadMultiply = 0x43,
+ kVK_ANSI_KeypadPlus = 0x45,
+ kVK_ANSI_KeypadClear = 0x47,
+ kVK_ANSI_KeypadDivide = 0x4B,
+ kVK_ANSI_KeypadEnter = 0x4C,
+ kVK_ANSI_KeypadMinus = 0x4E,
+ kVK_ANSI_KeypadEquals = 0x51,
+ kVK_ANSI_Keypad0 = 0x52,
+ kVK_ANSI_Keypad1 = 0x53,
+ kVK_ANSI_Keypad2 = 0x54,
+ kVK_ANSI_Keypad3 = 0x55,
+ kVK_ANSI_Keypad4 = 0x56,
+ kVK_ANSI_Keypad5 = 0x57,
+ kVK_ANSI_Keypad6 = 0x58,
+ kVK_ANSI_Keypad7 = 0x59,
+ kVK_ANSI_Keypad8 = 0x5B,
+ kVK_ANSI_Keypad9 = 0x5C
+};
+
+/* keycodes for keys that are independent of keyboard layout*/
+enum {
+ kVK_Return = 0x24,
+ kVK_Tab = 0x30,
+ kVK_Space = 0x31,
+ kVK_Delete = 0x33,
+ kVK_Escape = 0x35,
+ kVK_Command = 0x37,
+ kVK_Shift = 0x38,
+ kVK_CapsLock = 0x39,
+ kVK_Option = 0x3A,
+ kVK_Control = 0x3B,
+ kVK_RightShift = 0x3C,
+ kVK_RightOption = 0x3D,
+ kVK_RightControl = 0x3E,
+ kVK_Function = 0x3F,
+ kVK_F17 = 0x40,
+ kVK_VolumeUp = 0x48,
+ kVK_VolumeDown = 0x49,
+ kVK_Mute = 0x4A,
+ kVK_F18 = 0x4F,
+ kVK_F19 = 0x50,
+ kVK_F20 = 0x5A,
+ kVK_F5 = 0x60,
+ kVK_F6 = 0x61,
+ kVK_F7 = 0x62,
+ kVK_F3 = 0x63,
+ kVK_F8 = 0x64,
+ kVK_F9 = 0x65,
+ kVK_F11 = 0x67,
+ kVK_F13 = 0x69,
+ kVK_F16 = 0x6A,
+ kVK_F14 = 0x6B,
+ kVK_F10 = 0x6D,
+ kVK_F12 = 0x6F,
+ kVK_F15 = 0x71,
+ kVK_Help = 0x72,
+ kVK_Home = 0x73,
+ kVK_PageUp = 0x74,
+ kVK_ForwardDelete = 0x75,
+ kVK_F4 = 0x76,
+ kVK_End = 0x77,
+ kVK_F2 = 0x78,
+ kVK_PageDown = 0x79,
+ kVK_F1 = 0x7A,
+ kVK_LeftArrow = 0x7B,
+ kVK_RightArrow = 0x7C,
+ kVK_DownArrow = 0x7D,
+ kVK_UpArrow = 0x7E
+};
+
+static char g_keycodeCharUnshifted[256] = {};
+static char g_keycodeCharShifted[256] = {};
+
+//static double g_Time = 0.0f;
+static bool g_MousePressed[3] = { false, false, false };
+static float g_mouseWheelX = 0.0f;
+static float g_mouseWheelY = 0.0f;
+
+static GLuint g_FontTexture = 0;
+static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0;
+static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0;
+static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0;
+static size_t g_VboSize = 0;
+static unsigned int g_VboHandle = 0, g_VaoHandle = 0;
+static float g_displayScale;
+
+static int usynergy_sockfd;
+static bool g_synergyPtrActive = false;
+static uint16_t g_mousePosX = 0;
+static uint16_t g_mousePosY = 0;
+
+static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data);
+bool ImGui_ImplIOS_CreateDeviceObjects();
+
+static NSString *g_serverName;
+
+uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie)
+{
+ // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since
+ // uSynergy does not support SSL.
+
+ NSLog( @"Connect Func!");
+ struct addrinfo hints, *res;
+
+ // first, load up address structs with getaddrinfo():
+ memset(&hints, 0, sizeof hints);
+ hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
+ hints.ai_socktype = SOCK_STREAM;
+
+ // get server address
+ getaddrinfo([g_serverName UTF8String], "24800", &hints, &res);
+
+ if (!res)
+ {
+ NSLog( @"Could not find server: %@", g_serverName );
+ return USYNERGY_FALSE;
+ }
+
+ // make a socket:
+ usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+
+ // connect it to the address and port we passed in to getaddrinfo():
+ int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen);
+ if (!ret) {
+ NSLog( @"Connect succeeded...");
+ } else {
+ NSLog( @"Connect failed, %d", ret );
+ }
+
+
+ return USYNERGY_TRUE;
+}
+
+uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length)
+{
+// NSLog( @"Send Func" );
+ send( usynergy_sockfd, buffer, length, 0 );
+
+ return USYNERGY_TRUE;
+}
+
+uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength)
+{
+ *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 );
+
+ return USYNERGY_TRUE;
+}
+
+void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs)
+{
+ usleep( timeMs * 1000 );
+}
+
+uint32_t ImGui_GetTimeFunc()
+{
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+
+ return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000);
+}
+
+void ImGui_TraceFunc(uSynergyCookie cookie, const char *text)
+{
+ puts(text);
+}
+
+void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active)
+{
+ g_synergyPtrActive = active;
+// printf( "Synergy: screen activate %s\n", active?"YES":"NO" );
+}
+
+void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY,
+ uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle)
+{
+// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY );
+ uSynergyContext *ctx = (uSynergyContext*)cookie;
+ g_mousePosX = x;
+ g_mousePosY = y;
+ g_mouseWheelX = wheelX;
+ g_mouseWheelY = wheelY;
+ g_MousePressed[0] = buttonLeft;
+ g_MousePressed[1] = buttonMiddle;
+ g_MousePressed[2] = buttonRight;
+
+ ctx->m_mouseWheelX = 0;
+ ctx->m_mouseWheelY = 0;
+}
+
+void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key,
+ uint16_t modifiers, uSynergyBool down, uSynergyBool repeat)
+{
+ int scanCode = key-1;
+// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false");
+ ImGuiIO& io = ImGui::GetIO();
+ io.KeysDown[key] = down;
+ io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT);
+ io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL);
+ io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT);
+ io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN);
+
+ // Add this as keyboard input
+ if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL))
+ {
+ // If this key maps to a character input, apply it
+ int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode];
+ io.AddInputCharacter((unsigned short)charForKeycode);
+ }
+
+}
+
+void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY)
+{
+ printf("Synergy: joystick callback TODO\n");
+}
+
+void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size)
+{
+ printf("Synergy: clipboard callback TODO\n" );
+}
+
+@interface ImGuiHelper ()
+{
+ BOOL _mouseDown;
+ BOOL _mouseTapped;
+ CGPoint _touchPos;
+
+ uSynergyContext _synergyCtx;
+ dispatch_queue_t _synergyQueue;
+}
+@property (nonatomic, weak) UIView *view;
+@property (nonatomic, strong) NSString *serverName;
+
+@end
+
+@implementation ImGuiHelper
+
+- (id) initWithView: (UIView *)view
+{
+ self = [super init];
+ if (self)
+ {
+ self.view = view;
+
+ [self setupImGuiHooks];
+ }
+ return self;
+}
+
+- (void)setupKeymaps
+{
+ // The keyboard mapping is a big headache. I tried for a while to find a better way to do this,
+ // but this was the best I could come up with. There are some device independent API's available
+ // to convert scan codes to unicode characters, but these are only available on mac and not
+ // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do
+ // this or any way to get the character codes out of usynergy.
+ g_keycodeCharUnshifted[ kVK_ANSI_A ]='a';
+ g_keycodeCharUnshifted[ kVK_ANSI_S ]='s';
+ g_keycodeCharUnshifted[ kVK_ANSI_D ]='d';
+ g_keycodeCharUnshifted[ kVK_ANSI_F ]='f';
+ g_keycodeCharUnshifted[ kVK_ANSI_H ]='h';
+ g_keycodeCharUnshifted[ kVK_ANSI_G ]='g';
+ g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z';
+ g_keycodeCharUnshifted[ kVK_ANSI_X ]='x';
+ g_keycodeCharUnshifted[ kVK_ANSI_C ]='c';
+ g_keycodeCharUnshifted[ kVK_ANSI_V ]='v';
+ g_keycodeCharUnshifted[ kVK_ANSI_B ]='b';
+ g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q';
+ g_keycodeCharUnshifted[ kVK_ANSI_W ]='w';
+ g_keycodeCharUnshifted[ kVK_ANSI_E ]='e';
+ g_keycodeCharUnshifted[ kVK_ANSI_R ]='r';
+ g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y';
+ g_keycodeCharUnshifted[ kVK_ANSI_T ]='t';
+ g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1';
+ g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2';
+ g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3';
+ g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4';
+ g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6';
+ g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5';
+ g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='=';
+ g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9';
+ g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7';
+ g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-';
+ g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8';
+ g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0';
+ g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']';
+ g_keycodeCharUnshifted[ kVK_ANSI_O ]='o';
+ g_keycodeCharUnshifted[ kVK_ANSI_U ]='u';
+ g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='[';
+ g_keycodeCharUnshifted[ kVK_ANSI_I ]='i';
+ g_keycodeCharUnshifted[ kVK_ANSI_P ]='p';
+ g_keycodeCharUnshifted[ kVK_ANSI_L ]='l';
+ g_keycodeCharUnshifted[ kVK_ANSI_J ]='j';
+ g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\'';
+ g_keycodeCharUnshifted[ kVK_ANSI_K ]='k';
+ g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';';
+ g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\';
+ g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=',';
+ g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/';
+ g_keycodeCharUnshifted[ kVK_ANSI_N ]='n';
+ g_keycodeCharUnshifted[ kVK_ANSI_M ]='m';
+ g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.';
+ g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='=';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9';
+ g_keycodeCharUnshifted[ kVK_Space ]=' ';
+
+ g_keycodeCharShifted[ kVK_ANSI_A ]='A';
+ g_keycodeCharShifted[ kVK_ANSI_S ]='S';
+ g_keycodeCharShifted[ kVK_ANSI_D ]='D';
+ g_keycodeCharShifted[ kVK_ANSI_F ]='F';
+ g_keycodeCharShifted[ kVK_ANSI_H ]='H';
+ g_keycodeCharShifted[ kVK_ANSI_G ]='G';
+ g_keycodeCharShifted[ kVK_ANSI_Z ]='Z';
+ g_keycodeCharShifted[ kVK_ANSI_X ]='X';
+ g_keycodeCharShifted[ kVK_ANSI_C ]='C';
+ g_keycodeCharShifted[ kVK_ANSI_V ]='V';
+ g_keycodeCharShifted[ kVK_ANSI_B ]='B';
+ g_keycodeCharShifted[ kVK_ANSI_Q ]='Q';
+ g_keycodeCharShifted[ kVK_ANSI_W ]='W';
+ g_keycodeCharShifted[ kVK_ANSI_E ]='E';
+ g_keycodeCharShifted[ kVK_ANSI_R ]='R';
+ g_keycodeCharShifted[ kVK_ANSI_Y ]='Y';
+ g_keycodeCharShifted[ kVK_ANSI_T ]='T';
+ g_keycodeCharShifted[ kVK_ANSI_1 ]='!';
+ g_keycodeCharShifted[ kVK_ANSI_2 ]='@';
+ g_keycodeCharShifted[ kVK_ANSI_3 ]='#';
+ g_keycodeCharShifted[ kVK_ANSI_4 ]='$';
+ g_keycodeCharShifted[ kVK_ANSI_6 ]='^';
+ g_keycodeCharShifted[ kVK_ANSI_5 ]='%';
+ g_keycodeCharShifted[ kVK_ANSI_Equal ]='+';
+ g_keycodeCharShifted[ kVK_ANSI_9 ]='(';
+ g_keycodeCharShifted[ kVK_ANSI_7 ]='&';
+ g_keycodeCharShifted[ kVK_ANSI_Minus ]='_';
+ g_keycodeCharShifted[ kVK_ANSI_8 ]='*';
+ g_keycodeCharShifted[ kVK_ANSI_0 ]=')';
+ g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}';
+ g_keycodeCharShifted[ kVK_ANSI_O ]='O';
+ g_keycodeCharShifted[ kVK_ANSI_U ]='U';
+ g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{';
+ g_keycodeCharShifted[ kVK_ANSI_I ]='I';
+ g_keycodeCharShifted[ kVK_ANSI_P ]='P';
+ g_keycodeCharShifted[ kVK_ANSI_L ]='L';
+ g_keycodeCharShifted[ kVK_ANSI_J ]='J';
+ g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"';
+ g_keycodeCharShifted[ kVK_ANSI_K ]='K';
+ g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':';
+ g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|';
+ g_keycodeCharShifted[ kVK_ANSI_Comma ]='<';
+ g_keycodeCharShifted[ kVK_ANSI_Slash ]='?';
+ g_keycodeCharShifted[ kVK_ANSI_N ]='N';
+ g_keycodeCharShifted[ kVK_ANSI_M ]='M';
+ g_keycodeCharShifted[ kVK_ANSI_Period ]='>';
+ g_keycodeCharShifted[ kVK_ANSI_Grave ]='~';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='=';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9';
+ g_keycodeCharShifted[ kVK_Space ]=' ';
+}
+
+- (void)setupImGuiHooks
+{
+ ImGuiIO &io = ImGui::GetIO();
+
+ [self setupKeymaps];
+
+ // Account for retina display for glScissor
+ g_displayScale = [[UIScreen mainScreen] scale];
+
+ ImGuiStyle &style = ImGui::GetStyle();
+ style.TouchExtraPadding = ImVec2( 4.0, 4.0 );
+
+ io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists;
+
+ UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ];
+ [self.view addGestureRecognizer:panRecognizer];
+
+ UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)];
+ [self.view addGestureRecognizer:tapRecoginzer];
+
+ // Fill out the Synergy key map
+ // (for some reason synergy scan codes are off by 1)
+ io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1;
+ io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1;
+ io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1;
+ io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1;
+ io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1;
+ io.KeyMap[ImGuiKey_Home] = kVK_Home+1;
+ io.KeyMap[ImGuiKey_End] = kVK_End+1;
+ io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1;
+ io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1;
+ io.KeyMap[ImGuiKey_Enter] = kVK_Return+1;
+ io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1;
+ io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1;
+ io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1;
+ io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1;
+ io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1;
+ io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1;
+ io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1;
+}
+
+- (void)connectServer: (NSString*)serverName
+{
+ self.serverName = serverName;
+ g_serverName = serverName;
+
+ // Init synergy
+ NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey];
+
+ uSynergyInit( &_synergyCtx );
+ _synergyCtx.m_clientName = strdup( [bundleName UTF8String] );
+ _synergyCtx.m_clientWidth = self.view.bounds.size.width;
+ _synergyCtx.m_clientHeight = self.view.bounds.size.height;
+
+ _synergyCtx.m_connectFunc = ImGui_ConnectFunc;
+ _synergyCtx.m_sendFunc = ImGui_SendFunc;
+ _synergyCtx.m_receiveFunc = ImGui_RecvFunc;
+ _synergyCtx.m_sleepFunc = ImGui_SleepFunc;
+ _synergyCtx.m_traceFunc = ImGui_TraceFunc;
+ _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc;
+
+ _synergyCtx.m_traceFunc = ImGui_TraceFunc;
+ _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback;
+ _synergyCtx.m_mouseCallback = ImGui_MouseCallback;
+ _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback;
+
+ _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx;
+
+ // Create a background thread for synergy
+ _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL );
+ dispatch_async( _synergyQueue, ^{
+ while (1) {
+ uSynergyUpdate( &_synergyCtx );
+ }
+ });
+}
+
+
+- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer
+{
+
+ if ((recognizer.state == UIGestureRecognizerStateBegan) ||
+ (recognizer.state == UIGestureRecognizerStateChanged))
+ {
+ _mouseDown = YES;
+ _touchPos = [recognizer locationInView:self.view];
+ }
+ else
+ {
+ _mouseDown = NO;
+ _touchPos = CGPointMake( -1, -1 );
+ }
+}
+
+- (void)viewDidTap: (UITapGestureRecognizer*)recognizer
+{
+ _touchPos = [recognizer locationInView:self.view];
+ _mouseTapped = YES;
+}
+
+- (void)render
+{
+ ImGui::Render();
+}
+
+- (void)newFrame
+{
+ ImGuiIO& io = ImGui::GetIO();
+ ImGuiStyle &style = ImGui::GetStyle();
+
+ if (!g_FontTexture)
+ {
+ ImGui_ImplIOS_CreateDeviceObjects();
+ }
+
+ io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height );
+
+ io.MouseDrawCursor = g_synergyPtrActive;
+ if (g_synergyPtrActive)
+ {
+ style.TouchExtraPadding = ImVec2( 0.0, 0.0 );
+ io.MousePos = ImVec2( g_mousePosX, g_mousePosY );
+ for (int i=0; i < 3; i++)
+ {
+ io.MouseDown[i] = g_MousePressed[i];
+ }
+
+ // This is an arbitrary scaling factor that works for me. Not sure what units these
+ // mousewheel values from synergy are supposed to be in
+ io.MouseWheel = g_mouseWheelY / 500.0;
+ }
+ else
+ {
+ // Synergy not active, use touch events
+ style.TouchExtraPadding = ImVec2( 4.0, 4.0 );
+ io.MousePos = ImVec2(_touchPos.x, _touchPos.y );
+ if ((_mouseDown) || (_mouseTapped))
+ {
+ io.MouseDown[0] = true;
+ _mouseTapped = NO;
+ }
+ else
+ {
+ io.MouseDown[0] = false;
+ }
+ }
+
+ ImGui::NewFrame();
+}
+@end
+
+// 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)
+// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES
+static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data)
+{
+ // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled
+ GLint last_program, last_texture;
+ glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+ glEnable(GL_BLEND);
+ glBlendEquation(GL_FUNC_ADD);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_SCISSOR_TEST);
+ glActiveTexture(GL_TEXTURE0);
+
+ // Setup orthographic projection matrix
+ const float width = ImGui::GetIO().DisplaySize.x;
+ const float height = ImGui::GetIO().DisplaySize.y;
+ const float ortho_projection[4][4] =
+ {
+ { 2.0f/width, 0.0f, 0.0f, 0.0f },
+ { 0.0f, 2.0f/-height, 0.0f, 0.0f },
+ { 0.0f, 0.0f, -1.0f, 0.0f },
+ { -1.0f, 1.0f, 0.0f, 1.0f },
+ };
+ glUseProgram(g_ShaderHandle);
+ glUniform1i(g_AttribLocationTex, 0);
+ glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
+ glBindVertexArray(g_VaoHandle);
+
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
+ {
+ ImDrawList* cmd_list = draw_data->CmdLists[n];
+ ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front();
+
+ glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
+ const int needed_vtx_size = cmd_list->VtxBuffer.Size * sizeof(ImDrawVert);
+ if (g_VboSize < needed_vtx_size)
+ {
+ // Grow our buffer if needed
+ g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert);
+ glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW);
+ }
+
+ unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
+ if (!vtx_data)
+ continue;
+ memcpy(vtx_data, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
+ {
+ const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
+ if (pcmd->UserCallback)
+ {
+ pcmd->UserCallback(cmd_list, pcmd);
+ }
+ else
+ {
+ glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId);
+ glScissor((int)(pcmd->ClipRect.x * g_displayScale),
+ (int)((height - pcmd->ClipRect.w) * g_displayScale),
+ (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale),
+ (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale));
+ glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer );
+ }
+ idx_buffer += pcmd->ElemCount;
+ }
+ }
+
+ // Restore modified state
+ glBindVertexArray(0);
+ glBindBuffer( GL_ARRAY_BUFFER, 0);
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_DEPTH_TEST);
+ glUseProgram(last_program);
+ glDisable(GL_SCISSOR_TEST);
+ glBindTexture(GL_TEXTURE_2D, last_texture);
+}
+
+void ImGui_ImplIOS_CreateFontsTexture()
+{
+ // Build texture atlas
+ ImGuiIO& io = ImGui::GetIO();
+ unsigned char* pixels;
+ int width, height;
+ io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader.
+
+ // Upload texture to graphics system
+ GLint last_texture;
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+ glGenTextures(1, &g_FontTexture);
+ glBindTexture(GL_TEXTURE_2D, g_FontTexture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+
+ // Store our identifier
+ io.Fonts->TexID = (void *)(intptr_t)g_FontTexture;
+
+ // Restore state
+ glBindTexture(GL_TEXTURE_2D, last_texture);
+}
+
+bool ImGui_ImplIOS_CreateDeviceObjects()
+{
+ const GLchar *vertex_shader =
+ "uniform mat4 ProjMtx;\n"
+ "attribute highp vec2 Position;\n"
+ "attribute highp vec2 UV;\n"
+ "attribute highp vec4 Color;\n"
+ "varying vec2 Frag_UV;\n"
+ "varying vec4 Frag_Color;\n"
+ "void main()\n"
+ "{\n"
+ " Frag_UV = UV;\n"
+ " Frag_Color = Color;\n"
+ " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
+ "}\n";
+
+ const GLchar* fragment_shader =
+ "uniform sampler2D Texture;\n"
+ "varying highp vec2 Frag_UV;\n"
+ "varying highp vec4 Frag_Color;\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n"
+ "}\n";
+
+ g_ShaderHandle = glCreateProgram();
+ g_VertHandle = glCreateShader(GL_VERTEX_SHADER);
+ g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER);
+ glShaderSource(g_VertHandle, 1, &vertex_shader, 0);
+ glShaderSource(g_FragHandle, 1, &fragment_shader, 0);
+ glCompileShader(g_VertHandle);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log);
+ NSLog(@"VERTEX Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glCompileShader(g_FragHandle);
+
+#if defined(DEBUG)
+ glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log);
+ NSLog(@"FRAGMENT Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glAttachShader(g_ShaderHandle, g_VertHandle);
+ glAttachShader(g_ShaderHandle, g_FragHandle);
+ glLinkProgram(g_ShaderHandle);
+
+ g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture");
+ g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx");
+ g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position");
+ g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV");
+ g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color");
+
+ glGenBuffers(1, &g_VboHandle);
+
+ glGenVertexArrays(1, &g_VaoHandle);
+ glBindVertexArray(g_VaoHandle);
+ glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
+ glEnableVertexAttribArray(g_AttribLocationPosition);
+ glEnableVertexAttribArray(g_AttribLocationUV);
+ glEnableVertexAttribArray(g_AttribLocationColor);
+
+#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
+ glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos));
+ glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv));
+ glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col));
+#undef OFFSETOF
+ glBindVertexArray(0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ ImGui_ImplIOS_CreateFontsTexture();
+
+ return true;
+}
diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m
new file mode 100644
index 0000000..faba099
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/main.m
@@ -0,0 +1,13 @@
+//
+// main.m
+// imguiex
+//
+
+#import
+#import "AppDelegate.h"
+
+int main(int argc, char * argv[]) {
+ @autoreleasepool {
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+ }
+}
diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h
new file mode 100644
index 0000000..33d199b
--- /dev/null
+++ b/examples/apple_example/imguiex-osx/AppDelegate.h
@@ -0,0 +1,15 @@
+//
+// AppDelegate.h
+// imguiex-osx
+//
+// Created by James Chen on 4/5/16.
+// Copyright © 2016 Joel Davis. All rights reserved.
+//
+
+#import
+
+@interface AppDelegate : NSObject
+
+
+@end
+
diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m
new file mode 100644
index 0000000..59e877b
--- /dev/null
+++ b/examples/apple_example/imguiex-osx/AppDelegate.m
@@ -0,0 +1,26 @@
+//
+// AppDelegate.m
+// imguiex-osx
+//
+// Created by James Chen on 4/5/16.
+// Copyright © 2016 Joel Davis. All rights reserved.
+//
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@property (weak) IBOutlet NSWindow *window;
+@end
+
+@implementation AppDelegate
+
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
+ // Insert code here to initialize your application
+}
+
+- (void)applicationWillTerminate:(NSNotification *)aNotification {
+ // Insert code here to tear down your application
+}
+
+@end
diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..b13908f
--- /dev/null
+++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,64 @@
+{
+ "images" : [
+ {
+ "idiom" : "mac",
+ "size" : "16x16",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "16x16",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "32x32",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "32x32",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "128x128",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "128x128",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "256x256",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "256x256",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "512x512",
+ "scale" : "1x"
+ },
+ {
+ "size" : "512x512",
+ "idiom" : "mac",
+ "filename" : "icon_imgui_180x180.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "512x512",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 616d727..ccdb194 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,6 @@
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi
script:
- - make -C examples/opengl_example
+ - make -C examples/opengl2_example
- make -C examples/opengl3_example
diff --git a/README.md b/README.md
index 030cee9..68d57ee 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,9 @@
[](http://www.patreon.com/imgui) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-dear imgui (AKA 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 fast, portable, renderer agnostic and self-contained (no external dependencies).
+dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
-ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
+ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ 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 realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
@@ -33,23 +33,65 @@
ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. 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.
+_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
+
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 modern 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.
-Demo
-----
+Binaries/Demo
+-------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here.
-- [imgui-demo-binaries-20151226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20151226.zip) (Windows binaries, ImGui 1.47 2015/12/26, 4 executables, 515 KB)
+- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB)
+Bindings
+--------
+
+_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_
+
+_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_
+
+Languages:
+- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
+- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
+- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
+- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
+- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
+- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
+- LUA: https://github.com/patrickriordan/imgui_lua_bindings
+
+Frameworks:
+- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
+- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
+- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
+- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
+- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
+- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
+- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
+- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
+- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
+- LÖVE backend for dear imgui https://github.com/slages/love-imgui
+- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
+- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
+- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
+- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
+- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
+- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
+
+For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
+Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------
See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations.
-
-
-
+
+[](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
+
+
+[](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png)
+
+



@@ -91,18 +133,22 @@
The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
How do I update to a newer version of ImGui?
-
Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
+
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
+
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs.
+
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
How can I load a different font than the default?
+
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
+
How can I use the drawing facilities without an ImGui window? (using ImDrawList API)
See the FAQ in imgui.cpp for answers.
How do you use ImGui on a platform that may not have a mouse or keyboard?
-I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
+I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate.
Can you create elaborate/serious tools with ImGui?
@@ -112,7 +158,7 @@
Is ImGui fast?
-Probably fast enough for most uses. Down to 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.
+Probably fast enough for most uses. Down to the foundation 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 can give you a rough 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 are likely to be the bottleneck. Testing performance as part of a real application is recommended).
@@ -158,13 +204,19 @@
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
-ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
+Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui).
-Special supporters:
-- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano.
+Double-chocolate sponsors:
+- Media Molecule
+- Mobigame
+- Insomniac Games (sponsored the gamepad/keyboard navigation branch)
+- Aras Pranckevičius
-And:
-- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm.
+Salty caramel supporters:
+- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko.
+
+Caramel supporters:
+- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix.
And other supporters; thanks!
diff --git a/examples/.gitignore b/examples/.gitignore
index 8157aff..54d1539 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -15,11 +15,11 @@
directx11_example/Release/*
directx11_example/ipch/*
directx11_example/x64/*
-opengl_example/Debug/*
-opengl_example/Release/*
-opengl_example/ipch/*
-opengl_example/x64/*
-opengl_example/opengl_example
+opengl2_example/Debug/*
+opengl2_example/Release/*
+opengl2_example/ipch/*
+opengl2_example/x64/*
+opengl2_example/opengl_example
opengl3_example/Debug/*
opengl3_example/Release/*
opengl3_example/ipch/*
@@ -33,6 +33,7 @@
*.obj
*.exe
*.pdb
+*.ilk
## Ini files
imgui.ini
diff --git a/examples/README.txt b/examples/README.txt
index 11d785d..a20f4cb 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -1,13 +1,20 @@
Those are standalone ready-to-build applications to demonstrate ImGui.
-Binaries of some of those demos are available at http://www.miracleworld.net/imgui/binaries
+Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries
+
+Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links
+(languages: C, .net, rust, D, Python, Lua..)
+(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..)
+(extras: RemoteImGui, ImWindow, imgui_wm..)
TL;DR;
- Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase.
- - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one.
+ - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one.
The other examples requires more boilerplate and are harder to read.
+ - If you are using OpenGL in your application, probably use an opengl3_xxx backend.
+ Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers.
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files
to your project and use them unmodified.
- - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to
+ - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to
your engine, but you can read the other examples as well.
ImGui is highly portable and only requires a few things to run:
@@ -31,20 +38,19 @@
At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through
a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may
experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize
-the lag between an hardware cursor and a software cursor. It might be beneficial to the user experience
+the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience
to switch to a software rendered cursor when an interactive drag is in progress.
Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering),
leaving you with no option but sadness/anger (Intel GPU drivers were reported as such).
-opengl_example/
- OpenGL example, using GLFW + fixed pipeline.
- This is simple and should work for all OpenGL enabled applications.
- Prefer following this example to learn how ImGui works!
- (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline
- by calling "glUseProgram(0)" before ImGui::Render.)
+opengl2_example/
+ GLFW + OpenGL example (old fixed pipeline).
+ This is simple to read. Prefer following this example to learn how ImGui works!
+ (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable
+ pipeline by calling "glUseProgram(0)" before ImGui::Render.)
opengl3_example/
- OpenGL example, using GLFW/GL3W + programmable pipeline.
+ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W).
This uses more modern OpenGL calls and custom shaders. It's more messy.
directx9_example/
@@ -62,15 +68,15 @@
DirectX12 example, Windows only.
This is quite long and tedious, because: DirectX12.
-ios_example/
- iOS example.
- Using Synergy to access keyboard/mouse data from server computer.
+apple_example/
+ OSX & iOS example.
+ On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky.
-sdl_opengl_example/
- SDL2 + OpenGL example.
+sdl_opengl2_example/
+ SDL2 + OpenGL example (old fixed pipeline).
-sdl_opengl_example/
+sdl_opengl3_example/
SDL2 + OpenGL3 example.
allegro5_example/
@@ -78,4 +84,8 @@
marmalade_example/
Marmalade example using IwGx
-
+
+vulkan_example/
+ Vulkan example.
+ This is quite long and tedious, because: Vulkan.
+
diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp
index 0b1b8ed..9a04ff9 100644
--- a/examples/allegro5_example/imgui_impl_a5.cpp
+++ b/examples/allegro5_example/imgui_impl_a5.cpp
@@ -1,4 +1,9 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
+// TODO:
+// - Clipboard is not supported.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
@@ -38,14 +43,14 @@
al_get_blender(&op, &src, &dst);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
- for (int n = 0; n < draw_data->CmdListsCount; n++)
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats
static ImVector vertices;
- vertices.resize(cmd_list->VtxBuffer.size());
- for (int i = 0; i < cmd_list->VtxBuffer.size(); ++i)
+ vertices.resize(cmd_list->VtxBuffer.Size);
+ for (int i = 0; i < cmd_list->VtxBuffer.Size; ++i)
{
const ImDrawVert &dv = cmd_list->VtxBuffer[i];
ImDrawVertAllegro v;
@@ -59,19 +64,19 @@
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices
// You can also use '#define ImDrawIdx unsigned int' in imconfig.h and request ImGui to output 32-bit indices
static ImVector indices;
- indices.resize(cmd_list->IdxBuffer.size());
- for (int i = 0; i < cmd_list->IdxBuffer.size(); ++i)
+ indices.resize(cmd_list->IdxBuffer.Size);
+ for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
indices[i] = (int)cmd_list->IdxBuffer.Data[i];
int idx_offset = 0;
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- if (pcmd->UserCallback)
+ if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
- else
+ else
{
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z-pcmd->ClipRect.x, pcmd->ClipRect.w-pcmd->ClipRect.y);
@@ -102,11 +107,11 @@
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
al_set_new_bitmap_flags(flags);
al_set_new_bitmap_format(fmt);
- if (!img)
+ if (!img)
return false;
ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
- if (!locked_img)
+ if (!locked_img)
{
al_destroy_bitmap(img);
return false;
@@ -117,7 +122,7 @@
// Convert software texture to hardware texture.
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
al_destroy_bitmap(img);
- if (!cloned_img)
+ if (!cloned_img)
return false;
// Store our identifier
@@ -135,7 +140,7 @@
void ImGui_ImplA5_InvalidateDeviceObjects()
{
- if (g_Texture)
+ if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
@@ -151,11 +156,11 @@
bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display)
{
g_Display = display;
-
- // Create custom vertex declaration.
+
+ // Create custom vertex declaration.
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
- ALLEGRO_VERTEX_ELEMENT elems[] =
+ ALLEGRO_VERTEX_ELEMENT elems[] =
{
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) },
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) },
@@ -203,13 +208,13 @@
{
ImGuiIO &io = ImGui::GetIO();
- switch (ev->type)
+ switch (ev->type)
{
case ALLEGRO_EVENT_MOUSE_AXES:
io.MouseWheel += ev->mouse.dz;
return true;
case ALLEGRO_EVENT_KEY_CHAR:
- if (ev->keyboard.display == g_Display)
+ if (ev->keyboard.display == g_Display)
if (ev->keyboard.unichar > 0 && ev->keyboard.unichar < 0x10000)
io.AddInputCharacter((unsigned short)ev->keyboard.unichar);
return true;
@@ -225,7 +230,7 @@
void ImGui_ImplA5_NewFrame()
{
- if (!g_Texture)
+ if (!g_Texture)
Imgui_ImplA5_CreateDeviceObjects();
ImGuiIO &io = ImGui::GetIO();
@@ -247,14 +252,15 @@
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
+ io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
ALLEGRO_MOUSE_STATE mouse;
- if (keys.display == g_Display)
+ if (keys.display == g_Display)
{
al_get_mouse_state(&mouse);
io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
}
- else
+ else
{
io.MousePos = ImVec2(-1, -1);
}
diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h
index 721f510..b7439fe 100644
--- a/examples/allegro5_example/imgui_impl_a5.h
+++ b/examples/allegro5_example/imgui_impl_a5.h
@@ -1,4 +1,6 @@
// ImGui Allegro 5 bindings
+// In this binding, ImTextureID is used to store a 'ALLEGRO_BITMAP*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp
index ee89c7c..a8cd156 100644
--- a/examples/allegro5_example/main.cpp
+++ b/examples/allegro5_example/main.cpp
@@ -9,7 +9,7 @@
int main(int, char**)
{
- // Setup Allegro
+ // Setup Allegro
al_init();
al_install_keyboard();
al_install_mouse();
@@ -41,7 +41,7 @@
// Main loop
bool running = true;
- while (running)
+ while (running)
{
ALLEGRO_EVENT ev;
while (al_get_next_event(queue, &ev))
@@ -70,7 +70,7 @@
}
// 2. Show another simple window, this time using an explicit Begin/End pair
- if (show_another_window)
+ if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
@@ -79,7 +79,7 @@
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
- if (show_test_window)
+ if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore
new file mode 100644
index 0000000..8feda89
--- /dev/null
+++ b/examples/apple_example/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+imguiex.xcodeproj/project.xcworkspace/
+imguiex.xcodeproj/xcuserdata/
\ No newline at end of file
diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md
new file mode 100644
index 0000000..339f6bf
--- /dev/null
+++ b/examples/apple_example/README.md
@@ -0,0 +1,41 @@
+# iOS / OSX example
+
+## Introduction
+
+This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device.
+
+It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy.
+
+Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active.
+
+## How to Use on iOS
+
+* In Synergy, go to Preferences, and uncheck "Use SSL encryption"
+* Run the example app.
+* Tap the "servername" button in the corner
+* Enter the name or the IP of your synergy host
+* If you had previously connected to a server, you may need to kill and re-start the app.
+
+## How to Build on OSX
+
+* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh)
+* Run the command: `brew install glfw3`
+* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme
+* Click `Run` button
+
+## Notes and TODOs
+
+Things that would be nice but I didn't get around to doing:
+
+* iOS software keyboard not supported for text inputs
+* iOS hardware (bluetooth) keyboards not supported
+* Graceful disconnect/reconnect from uSynergy.
+* Copy/Paste not well-supported
+
+## C++ on iOS / OSX
+
+ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension.
+
+Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer.
+
+In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly.
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h
new file mode 100644
index 0000000..82f1542
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.h
@@ -0,0 +1,13 @@
+//
+// AppDelegate.h
+// imguiex
+
+#import
+
+@interface AppDelegate : UIResponder
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m
new file mode 100644
index 0000000..ab83101
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/AppDelegate.m
@@ -0,0 +1,41 @@
+//
+// AppDelegate.m
+// imguiex
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Override point for customization after application launch.
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
new file mode 100644
index 0000000..5717c00
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..90dfb2e
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h
new file mode 100644
index 0000000..3323cfd
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.h
@@ -0,0 +1,12 @@
+//
+// GameViewController.h
+// imguiex
+
+// This is the OpenGL Example template from XCode, modified to support ImGui
+
+#import
+#import
+
+@interface GameViewController : GLKViewController
+
+@end
diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m
new file mode 100644
index 0000000..e902f7a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/GameViewController.m
@@ -0,0 +1,481 @@
+//
+// GameViewController.m
+// imguiex
+//
+#import "GameViewController.h"
+#import
+
+#import "imgui_impl_ios.h"
+#import "debug_hud.h"
+
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
+
+#define SERVERNAME_KEY @"ServerName"
+
+#define SERVERNAME_ALERT_TAG (10)
+
+// Uniform index.
+enum
+{
+ UNIFORM_MODELVIEWPROJECTION_MATRIX,
+ UNIFORM_NORMAL_MATRIX,
+ UNIFORM_DIFFUSE_COLOR,
+
+ NUM_UNIFORMS
+};
+GLint uniforms[NUM_UNIFORMS];
+
+// Attribute index.
+enum
+{
+ ATTRIB_VERTEX,
+ ATTRIB_NORMAL,
+ NUM_ATTRIBUTES
+};
+
+GLfloat gCubeVertexData[216] =
+{
+ // Data layout for each line below is:
+ // positionX, positionY, positionZ, normalX, normalY, normalZ,
+ 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
+
+ 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
+
+ -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
+
+ -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
+
+ 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+ -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
+
+ 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
+ -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f
+};
+
+@interface GameViewController ()
+{
+ GLuint _program;
+
+ GLKMatrix4 _modelViewProjectionMatrix;
+ GLKMatrix3 _normalMatrix;
+ float _rotation;
+
+ GLuint _vertexArray;
+ GLuint _vertexBuffer;
+
+ DebugHUD _hud;
+}
+@property (strong, nonatomic) EAGLContext *context;
+@property (strong, nonatomic) GLKBaseEffect *effect;
+@property (strong, nonatomic) ImGuiHelper *imgui;
+@property (weak, nonatomic) IBOutlet UIButton *btnServername;
+
+@property (strong, nonatomic) NSString *serverName;
+
+- (IBAction)onServernameTapped:(id)sender;
+
+- (void)setupGL;
+- (void)tearDownGL;
+
+- (BOOL)loadShaders;
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file;
+- (BOOL)linkProgram:(GLuint)prog;
+- (BOOL)validateProgram:(GLuint)prog;
+@end
+
+@implementation GameViewController
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+
+ if (!self.context) {
+ NSLog(@"Failed to create ES context");
+ }
+
+ GLKView *view = (GLKView *)self.view;
+ view.context = self.context;
+ view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
+
+ [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
+
+ [self setupGL];
+
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ];
+ self.imgui = [[ImGuiHelper alloc] initWithView:self.view ];
+ if (self.serverName)
+ {
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+ [self.imgui connectServer: self.serverName ];
+ }
+
+ DebugHUD_InitDefaults( &_hud );
+}
+
+- (void)dealloc
+{
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+
+ if ([self isViewLoaded] && ([[self view] window] == nil)) {
+ self.view = nil;
+
+ [self tearDownGL];
+
+ if ([EAGLContext currentContext] == self.context) {
+ [EAGLContext setCurrentContext:nil];
+ }
+ self.context = nil;
+ }
+
+ // Dispose of any resources that can be recreated.
+}
+
+
+- (BOOL)prefersStatusBarHidden {
+ return YES;
+}
+
+- (IBAction)onServernameTapped:(id)sender
+{
+ UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ];
+ alert.alertViewStyle = UIAlertViewStylePlainTextInput;
+ alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to
+ [alert show];
+}
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG))
+ {
+ // This is really janky. I usually just hardcode the servername since I'm building it anyway.
+ // If you want to properly handle updating the server, you'll want to tear down and recreate
+ // the usynergy stuff in connectServer
+ BOOL serverNameWasSet = self.serverName.length > 0;
+ NSString *serverName = [[alertView textFieldAtIndex:0] text];
+
+ if ([serverName length] > 0) {
+ self.serverName = serverName;
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ [userDefaults setObject:serverName forKey:SERVERNAME_KEY ];
+ [userDefaults synchronize];
+
+ [self.btnServername setTitle:self.serverName forState:UIControlStateNormal];
+
+ // If we hadn't previously connected, try now
+ if (!serverNameWasSet) {
+ [self.imgui connectServer:self.serverName];
+ }
+ else
+ {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated"
+ message:@"Restart the app to connect the server"
+ delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
+ [alert show];
+ }
+ }
+ }
+}
+
+- (void)setupGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ [self loadShaders];
+
+ self.effect = [[GLKBaseEffect alloc] init];
+ self.effect.light0.enabled = GL_TRUE;
+ self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f);
+
+ glEnable(GL_DEPTH_TEST);
+
+ glGenVertexArraysOES(1, &_vertexArray);
+ glBindVertexArrayOES(_vertexArray);
+
+ glGenBuffers(1, &_vertexBuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);
+
+ glEnableVertexAttribArray(GLKVertexAttribPosition);
+ glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
+ glEnableVertexAttribArray(GLKVertexAttribNormal);
+ glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
+
+ glBindVertexArrayOES(0);
+
+
+}
+
+- (void)tearDownGL
+{
+ [EAGLContext setCurrentContext:self.context];
+
+ glDeleteBuffers(1, &_vertexBuffer);
+ glDeleteVertexArraysOES(1, &_vertexArray);
+
+ self.effect = nil;
+
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+}
+
+#pragma mark - GLKView and GLKViewController delegate methods
+
+- (void)update
+{
+ float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height);
+ GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
+
+ self.effect.transform.projectionMatrix = projectionMatrix;
+
+ GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);
+ baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
+
+ // Compute the model view matrix for the object rendered with GLKit
+ GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ self.effect.transform.modelviewMatrix = modelViewMatrix;
+
+ // Compute the model view matrix for the object rendered with ES2
+ modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f);
+ modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
+ modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
+
+ _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
+
+ _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
+
+ _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0));
+}
+
+
+- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
+{
+ glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glBindVertexArrayOES(_vertexArray);
+
+ // Render the object with GLKit
+ [self.effect prepareToDraw];
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ // Render the object again with ES2
+ glUseProgram(_program);
+
+ glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
+ glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
+ glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] );
+
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+
+ [self.imgui newFrame];
+
+ // Now do our ImGUI UI
+ DebugHUD_DoInterface( &_hud );
+
+ self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f);
+
+ // Now render Imgui
+ [self.imgui render];
+
+}
+
+#pragma mark - OpenGL ES 2 shader compilation
+
+- (BOOL)loadShaders
+{
+ GLuint vertShader, fragShader;
+ NSString *vertShaderPathname, *fragShaderPathname;
+
+ // Create shader program.
+ _program = glCreateProgram();
+
+ // Create and compile vertex shader.
+ vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
+ if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
+ NSLog(@"Failed to compile vertex shader");
+ return NO;
+ }
+
+ // Create and compile fragment shader.
+ fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
+ if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
+ NSLog(@"Failed to compile fragment shader");
+ return NO;
+ }
+
+ // Attach vertex shader to program.
+ glAttachShader(_program, vertShader);
+
+ // Attach fragment shader to program.
+ glAttachShader(_program, fragShader);
+
+ // Bind attribute locations.
+ // This needs to be done prior to linking.
+ glBindAttribLocation(_program, GLKVertexAttribPosition, "position");
+ glBindAttribLocation(_program, GLKVertexAttribNormal, "normal");
+
+ // Link program.
+ if (![self linkProgram:_program]) {
+ NSLog(@"Failed to link program: %d", _program);
+
+ if (vertShader) {
+ glDeleteShader(vertShader);
+ vertShader = 0;
+ }
+ if (fragShader) {
+ glDeleteShader(fragShader);
+ fragShader = 0;
+ }
+ if (_program) {
+ glDeleteProgram(_program);
+ _program = 0;
+ }
+
+ return NO;
+ }
+
+ // Get uniform locations.
+ uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix");
+ uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix");
+ uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor");
+
+ // Release vertex and fragment shaders.
+ if (vertShader) {
+ glDetachShader(_program, vertShader);
+ glDeleteShader(vertShader);
+ }
+ if (fragShader) {
+ glDetachShader(_program, fragShader);
+ glDeleteShader(fragShader);
+ }
+
+ return YES;
+}
+
+- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
+{
+ GLint status;
+ const GLchar *source;
+
+ source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
+ if (!source) {
+ NSLog(@"Failed to load vertex shader");
+ return NO;
+ }
+
+ *shader = glCreateShader(type);
+ glShaderSource(*shader, 1, &source, NULL);
+ glCompileShader(*shader);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(*shader, logLength, &logLength, log);
+ NSLog(@"Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
+ if (status == 0) {
+ glDeleteShader(*shader);
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)linkProgram:(GLuint)prog
+{
+ GLint status;
+ glLinkProgram(prog);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program link log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetProgramiv(prog, GL_LINK_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)validateProgram:(GLuint)prog
+{
+ GLint logLength, status;
+
+ glValidateProgram(prog);
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ NSLog(@"Program validate log:\n%s", log);
+ free(log);
+ }
+
+ glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
+ if (status == 0) {
+ return NO;
+ }
+
+ return YES;
+}
+
+@end
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..06b60d8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,77 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@2x~iphone.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "icon_imgui_60@3x~iphone.png",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76~ipad.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "icon_imgui_76@2x~ipad.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "83.5x83.5",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
new file mode 100644
index 0000000..d728bc3
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
new file mode 100644
index 0000000..f48b799
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
new file mode 100644
index 0000000..67b08b8
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
new file mode 100644
index 0000000..ae88e04
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist
new file mode 100644
index 0000000..bc6f548
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Info.plist
@@ -0,0 +1,49 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ org.imgui.example.$(PRODUCT_NAME:rfc1034identifier)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UIStatusBarHidden
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh
new file mode 100644
index 0000000..4000524
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh
@@ -0,0 +1,10 @@
+//
+// Shader.fsh
+// imguiex
+
+varying lowp vec4 colorVarying;
+
+void main()
+{
+ gl_FragColor = colorVarying;
+}
diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh
new file mode 100644
index 0000000..313c3d7
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh
@@ -0,0 +1,25 @@
+//
+// Shader.vsh
+// imguiex
+
+attribute vec4 position;
+attribute vec3 normal;
+
+varying lowp vec4 colorVarying;
+
+uniform vec3 diffuseColor;
+uniform mat4 modelViewProjectionMatrix;
+uniform mat3 normalMatrix;
+
+void main()
+{
+ vec3 eyeNormal = normalize(normalMatrix * normal);
+ vec3 lightPosition = vec3(0.0, 0.0, 1.0);
+
+ float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition)));
+
+ vec3 colorLit = diffuseColor * nDotVP;
+ colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 );
+
+ gl_Position = modelViewProjectionMatrix * position;
+}
diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp
new file mode 100644
index 0000000..c75938a
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/debug_hud.cpp
@@ -0,0 +1,45 @@
+//
+// debug_hud.cpp
+// imguiex
+
+#include
+
+#include "debug_hud.h"
+#include "imgui.h"
+
+void DebugHUD_InitDefaults( DebugHUD *hud )
+{
+ hud->show_test_window = true;
+ hud->show_example_window = true;
+ hud->rotation_speed = 15.0f;
+
+ hud->cubeColor1[0] = 0.4f;
+ hud->cubeColor1[1] = 0.4f;
+ hud->cubeColor1[2] = 1.0f;
+ hud->cubeColor1[3] = 1.0f;
+
+ hud->cubeColor2[0] = 1.0f;
+ hud->cubeColor2[1] = 0.4f;
+ hud->cubeColor2[2] = 0.4f;
+ hud->cubeColor2[3] = 1.0f;
+}
+
+void DebugHUD_DoInterface( DebugHUD *hud )
+{
+ if (hud->show_test_window)
+ {
+ ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver );
+ ImGui::ShowTestWindow( &hud->show_test_window );
+ }
+
+ if (hud->show_example_window)
+ {
+ ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver );
+ ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver );
+ ImGui::Begin("Another Window", &hud->show_example_window);
+ ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1);
+ ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2);
+ ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f);
+ ImGui::End();
+ }
+}
diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h
new file mode 100644
index 0000000..17122f5
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/debug_hud.h
@@ -0,0 +1,25 @@
+//
+// debug_hud.h
+// imguiex
+
+#pragma once
+
+typedef struct DebugHUD
+{
+ bool show_test_window;
+ bool show_example_window;
+ float rotation_speed;
+ float cubeColor1[4];
+ float cubeColor2[4];
+} DebugHUD;
+
+#if __cplusplus
+extern "C" {
+#endif
+
+void DebugHUD_InitDefaults( DebugHUD *hud );
+void DebugHUD_DoInterface( DebugHUD *hud );
+
+#if __cplusplus
+}
+#endif
diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png
new file mode 100644
index 0000000..820e4d7
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png
Binary files differ
diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h
new file mode 100644
index 0000000..9b01dd3
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h
@@ -0,0 +1,22 @@
+// ImGui iOS+OpenGL+Synergy binding
+// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much.
+// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application.
+
+// by Joel Davis (joeld42@gmail.com)
+
+#pragma once
+
+#include
+#include
+
+@interface ImGuiHelper : NSObject
+
+- (id) initWithView: (UIView *)view;
+
+- (void)connectServer: (NSString*)serverName;
+
+- (void)render;
+- (void)newFrame;
+
+@end
diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm
new file mode 100644
index 0000000..893dbf9
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm
@@ -0,0 +1,806 @@
+// ImGui iOS+OpenGL+Synergy binding
+// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.
+// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much.
+// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application.
+
+// TODO:
+// - Clipboard is not supported.
+
+#import
+#import
+
+#include
+#include
+#include
+#include
+
+#include "imgui_impl_ios.h"
+#include "imgui.h"
+
+#include "uSynergy.h"
+
+// From Carbon HIToolbox/Events.h
+// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247
+enum {
+ kVK_ANSI_A = 0x00,
+ kVK_ANSI_S = 0x01,
+ kVK_ANSI_D = 0x02,
+ kVK_ANSI_F = 0x03,
+ kVK_ANSI_H = 0x04,
+ kVK_ANSI_G = 0x05,
+ kVK_ANSI_Z = 0x06,
+ kVK_ANSI_X = 0x07,
+ kVK_ANSI_C = 0x08,
+ kVK_ANSI_V = 0x09,
+ kVK_ANSI_B = 0x0B,
+ kVK_ANSI_Q = 0x0C,
+ kVK_ANSI_W = 0x0D,
+ kVK_ANSI_E = 0x0E,
+ kVK_ANSI_R = 0x0F,
+ kVK_ANSI_Y = 0x10,
+ kVK_ANSI_T = 0x11,
+ kVK_ANSI_1 = 0x12,
+ kVK_ANSI_2 = 0x13,
+ kVK_ANSI_3 = 0x14,
+ kVK_ANSI_4 = 0x15,
+ kVK_ANSI_6 = 0x16,
+ kVK_ANSI_5 = 0x17,
+ kVK_ANSI_Equal = 0x18,
+ kVK_ANSI_9 = 0x19,
+ kVK_ANSI_7 = 0x1A,
+ kVK_ANSI_Minus = 0x1B,
+ kVK_ANSI_8 = 0x1C,
+ kVK_ANSI_0 = 0x1D,
+ kVK_ANSI_RightBracket = 0x1E,
+ kVK_ANSI_O = 0x1F,
+ kVK_ANSI_U = 0x20,
+ kVK_ANSI_LeftBracket = 0x21,
+ kVK_ANSI_I = 0x22,
+ kVK_ANSI_P = 0x23,
+ kVK_ANSI_L = 0x25,
+ kVK_ANSI_J = 0x26,
+ kVK_ANSI_Quote = 0x27,
+ kVK_ANSI_K = 0x28,
+ kVK_ANSI_Semicolon = 0x29,
+ kVK_ANSI_Backslash = 0x2A,
+ kVK_ANSI_Comma = 0x2B,
+ kVK_ANSI_Slash = 0x2C,
+ kVK_ANSI_N = 0x2D,
+ kVK_ANSI_M = 0x2E,
+ kVK_ANSI_Period = 0x2F,
+ kVK_ANSI_Grave = 0x32,
+ kVK_ANSI_KeypadDecimal = 0x41,
+ kVK_ANSI_KeypadMultiply = 0x43,
+ kVK_ANSI_KeypadPlus = 0x45,
+ kVK_ANSI_KeypadClear = 0x47,
+ kVK_ANSI_KeypadDivide = 0x4B,
+ kVK_ANSI_KeypadEnter = 0x4C,
+ kVK_ANSI_KeypadMinus = 0x4E,
+ kVK_ANSI_KeypadEquals = 0x51,
+ kVK_ANSI_Keypad0 = 0x52,
+ kVK_ANSI_Keypad1 = 0x53,
+ kVK_ANSI_Keypad2 = 0x54,
+ kVK_ANSI_Keypad3 = 0x55,
+ kVK_ANSI_Keypad4 = 0x56,
+ kVK_ANSI_Keypad5 = 0x57,
+ kVK_ANSI_Keypad6 = 0x58,
+ kVK_ANSI_Keypad7 = 0x59,
+ kVK_ANSI_Keypad8 = 0x5B,
+ kVK_ANSI_Keypad9 = 0x5C
+};
+
+/* keycodes for keys that are independent of keyboard layout*/
+enum {
+ kVK_Return = 0x24,
+ kVK_Tab = 0x30,
+ kVK_Space = 0x31,
+ kVK_Delete = 0x33,
+ kVK_Escape = 0x35,
+ kVK_Command = 0x37,
+ kVK_Shift = 0x38,
+ kVK_CapsLock = 0x39,
+ kVK_Option = 0x3A,
+ kVK_Control = 0x3B,
+ kVK_RightShift = 0x3C,
+ kVK_RightOption = 0x3D,
+ kVK_RightControl = 0x3E,
+ kVK_Function = 0x3F,
+ kVK_F17 = 0x40,
+ kVK_VolumeUp = 0x48,
+ kVK_VolumeDown = 0x49,
+ kVK_Mute = 0x4A,
+ kVK_F18 = 0x4F,
+ kVK_F19 = 0x50,
+ kVK_F20 = 0x5A,
+ kVK_F5 = 0x60,
+ kVK_F6 = 0x61,
+ kVK_F7 = 0x62,
+ kVK_F3 = 0x63,
+ kVK_F8 = 0x64,
+ kVK_F9 = 0x65,
+ kVK_F11 = 0x67,
+ kVK_F13 = 0x69,
+ kVK_F16 = 0x6A,
+ kVK_F14 = 0x6B,
+ kVK_F10 = 0x6D,
+ kVK_F12 = 0x6F,
+ kVK_F15 = 0x71,
+ kVK_Help = 0x72,
+ kVK_Home = 0x73,
+ kVK_PageUp = 0x74,
+ kVK_ForwardDelete = 0x75,
+ kVK_F4 = 0x76,
+ kVK_End = 0x77,
+ kVK_F2 = 0x78,
+ kVK_PageDown = 0x79,
+ kVK_F1 = 0x7A,
+ kVK_LeftArrow = 0x7B,
+ kVK_RightArrow = 0x7C,
+ kVK_DownArrow = 0x7D,
+ kVK_UpArrow = 0x7E
+};
+
+static char g_keycodeCharUnshifted[256] = {};
+static char g_keycodeCharShifted[256] = {};
+
+//static double g_Time = 0.0f;
+static bool g_MousePressed[3] = { false, false, false };
+static float g_mouseWheelX = 0.0f;
+static float g_mouseWheelY = 0.0f;
+
+static GLuint g_FontTexture = 0;
+static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0;
+static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0;
+static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0;
+static size_t g_VboSize = 0;
+static unsigned int g_VboHandle = 0, g_VaoHandle = 0;
+static float g_displayScale;
+
+static int usynergy_sockfd;
+static bool g_synergyPtrActive = false;
+static uint16_t g_mousePosX = 0;
+static uint16_t g_mousePosY = 0;
+
+static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data);
+bool ImGui_ImplIOS_CreateDeviceObjects();
+
+static NSString *g_serverName;
+
+uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie)
+{
+ // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since
+ // uSynergy does not support SSL.
+
+ NSLog( @"Connect Func!");
+ struct addrinfo hints, *res;
+
+ // first, load up address structs with getaddrinfo():
+ memset(&hints, 0, sizeof hints);
+ hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
+ hints.ai_socktype = SOCK_STREAM;
+
+ // get server address
+ getaddrinfo([g_serverName UTF8String], "24800", &hints, &res);
+
+ if (!res)
+ {
+ NSLog( @"Could not find server: %@", g_serverName );
+ return USYNERGY_FALSE;
+ }
+
+ // make a socket:
+ usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+
+ // connect it to the address and port we passed in to getaddrinfo():
+ int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen);
+ if (!ret) {
+ NSLog( @"Connect succeeded...");
+ } else {
+ NSLog( @"Connect failed, %d", ret );
+ }
+
+
+ return USYNERGY_TRUE;
+}
+
+uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length)
+{
+// NSLog( @"Send Func" );
+ send( usynergy_sockfd, buffer, length, 0 );
+
+ return USYNERGY_TRUE;
+}
+
+uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength)
+{
+ *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 );
+
+ return USYNERGY_TRUE;
+}
+
+void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs)
+{
+ usleep( timeMs * 1000 );
+}
+
+uint32_t ImGui_GetTimeFunc()
+{
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+
+ return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000);
+}
+
+void ImGui_TraceFunc(uSynergyCookie cookie, const char *text)
+{
+ puts(text);
+}
+
+void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active)
+{
+ g_synergyPtrActive = active;
+// printf( "Synergy: screen activate %s\n", active?"YES":"NO" );
+}
+
+void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY,
+ uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle)
+{
+// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY );
+ uSynergyContext *ctx = (uSynergyContext*)cookie;
+ g_mousePosX = x;
+ g_mousePosY = y;
+ g_mouseWheelX = wheelX;
+ g_mouseWheelY = wheelY;
+ g_MousePressed[0] = buttonLeft;
+ g_MousePressed[1] = buttonMiddle;
+ g_MousePressed[2] = buttonRight;
+
+ ctx->m_mouseWheelX = 0;
+ ctx->m_mouseWheelY = 0;
+}
+
+void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key,
+ uint16_t modifiers, uSynergyBool down, uSynergyBool repeat)
+{
+ int scanCode = key-1;
+// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false");
+ ImGuiIO& io = ImGui::GetIO();
+ io.KeysDown[key] = down;
+ io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT);
+ io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL);
+ io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT);
+ io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN);
+
+ // Add this as keyboard input
+ if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL))
+ {
+ // If this key maps to a character input, apply it
+ int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode];
+ io.AddInputCharacter((unsigned short)charForKeycode);
+ }
+
+}
+
+void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY)
+{
+ printf("Synergy: joystick callback TODO\n");
+}
+
+void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size)
+{
+ printf("Synergy: clipboard callback TODO\n" );
+}
+
+@interface ImGuiHelper ()
+{
+ BOOL _mouseDown;
+ BOOL _mouseTapped;
+ CGPoint _touchPos;
+
+ uSynergyContext _synergyCtx;
+ dispatch_queue_t _synergyQueue;
+}
+@property (nonatomic, weak) UIView *view;
+@property (nonatomic, strong) NSString *serverName;
+
+@end
+
+@implementation ImGuiHelper
+
+- (id) initWithView: (UIView *)view
+{
+ self = [super init];
+ if (self)
+ {
+ self.view = view;
+
+ [self setupImGuiHooks];
+ }
+ return self;
+}
+
+- (void)setupKeymaps
+{
+ // The keyboard mapping is a big headache. I tried for a while to find a better way to do this,
+ // but this was the best I could come up with. There are some device independent API's available
+ // to convert scan codes to unicode characters, but these are only available on mac and not
+ // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do
+ // this or any way to get the character codes out of usynergy.
+ g_keycodeCharUnshifted[ kVK_ANSI_A ]='a';
+ g_keycodeCharUnshifted[ kVK_ANSI_S ]='s';
+ g_keycodeCharUnshifted[ kVK_ANSI_D ]='d';
+ g_keycodeCharUnshifted[ kVK_ANSI_F ]='f';
+ g_keycodeCharUnshifted[ kVK_ANSI_H ]='h';
+ g_keycodeCharUnshifted[ kVK_ANSI_G ]='g';
+ g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z';
+ g_keycodeCharUnshifted[ kVK_ANSI_X ]='x';
+ g_keycodeCharUnshifted[ kVK_ANSI_C ]='c';
+ g_keycodeCharUnshifted[ kVK_ANSI_V ]='v';
+ g_keycodeCharUnshifted[ kVK_ANSI_B ]='b';
+ g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q';
+ g_keycodeCharUnshifted[ kVK_ANSI_W ]='w';
+ g_keycodeCharUnshifted[ kVK_ANSI_E ]='e';
+ g_keycodeCharUnshifted[ kVK_ANSI_R ]='r';
+ g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y';
+ g_keycodeCharUnshifted[ kVK_ANSI_T ]='t';
+ g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1';
+ g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2';
+ g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3';
+ g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4';
+ g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6';
+ g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5';
+ g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='=';
+ g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9';
+ g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7';
+ g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-';
+ g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8';
+ g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0';
+ g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']';
+ g_keycodeCharUnshifted[ kVK_ANSI_O ]='o';
+ g_keycodeCharUnshifted[ kVK_ANSI_U ]='u';
+ g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='[';
+ g_keycodeCharUnshifted[ kVK_ANSI_I ]='i';
+ g_keycodeCharUnshifted[ kVK_ANSI_P ]='p';
+ g_keycodeCharUnshifted[ kVK_ANSI_L ]='l';
+ g_keycodeCharUnshifted[ kVK_ANSI_J ]='j';
+ g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\'';
+ g_keycodeCharUnshifted[ kVK_ANSI_K ]='k';
+ g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';';
+ g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\';
+ g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=',';
+ g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/';
+ g_keycodeCharUnshifted[ kVK_ANSI_N ]='n';
+ g_keycodeCharUnshifted[ kVK_ANSI_M ]='m';
+ g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.';
+ g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-';
+ g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='=';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8';
+ g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9';
+ g_keycodeCharUnshifted[ kVK_Space ]=' ';
+
+ g_keycodeCharShifted[ kVK_ANSI_A ]='A';
+ g_keycodeCharShifted[ kVK_ANSI_S ]='S';
+ g_keycodeCharShifted[ kVK_ANSI_D ]='D';
+ g_keycodeCharShifted[ kVK_ANSI_F ]='F';
+ g_keycodeCharShifted[ kVK_ANSI_H ]='H';
+ g_keycodeCharShifted[ kVK_ANSI_G ]='G';
+ g_keycodeCharShifted[ kVK_ANSI_Z ]='Z';
+ g_keycodeCharShifted[ kVK_ANSI_X ]='X';
+ g_keycodeCharShifted[ kVK_ANSI_C ]='C';
+ g_keycodeCharShifted[ kVK_ANSI_V ]='V';
+ g_keycodeCharShifted[ kVK_ANSI_B ]='B';
+ g_keycodeCharShifted[ kVK_ANSI_Q ]='Q';
+ g_keycodeCharShifted[ kVK_ANSI_W ]='W';
+ g_keycodeCharShifted[ kVK_ANSI_E ]='E';
+ g_keycodeCharShifted[ kVK_ANSI_R ]='R';
+ g_keycodeCharShifted[ kVK_ANSI_Y ]='Y';
+ g_keycodeCharShifted[ kVK_ANSI_T ]='T';
+ g_keycodeCharShifted[ kVK_ANSI_1 ]='!';
+ g_keycodeCharShifted[ kVK_ANSI_2 ]='@';
+ g_keycodeCharShifted[ kVK_ANSI_3 ]='#';
+ g_keycodeCharShifted[ kVK_ANSI_4 ]='$';
+ g_keycodeCharShifted[ kVK_ANSI_6 ]='^';
+ g_keycodeCharShifted[ kVK_ANSI_5 ]='%';
+ g_keycodeCharShifted[ kVK_ANSI_Equal ]='+';
+ g_keycodeCharShifted[ kVK_ANSI_9 ]='(';
+ g_keycodeCharShifted[ kVK_ANSI_7 ]='&';
+ g_keycodeCharShifted[ kVK_ANSI_Minus ]='_';
+ g_keycodeCharShifted[ kVK_ANSI_8 ]='*';
+ g_keycodeCharShifted[ kVK_ANSI_0 ]=')';
+ g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}';
+ g_keycodeCharShifted[ kVK_ANSI_O ]='O';
+ g_keycodeCharShifted[ kVK_ANSI_U ]='U';
+ g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{';
+ g_keycodeCharShifted[ kVK_ANSI_I ]='I';
+ g_keycodeCharShifted[ kVK_ANSI_P ]='P';
+ g_keycodeCharShifted[ kVK_ANSI_L ]='L';
+ g_keycodeCharShifted[ kVK_ANSI_J ]='J';
+ g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"';
+ g_keycodeCharShifted[ kVK_ANSI_K ]='K';
+ g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':';
+ g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|';
+ g_keycodeCharShifted[ kVK_ANSI_Comma ]='<';
+ g_keycodeCharShifted[ kVK_ANSI_Slash ]='?';
+ g_keycodeCharShifted[ kVK_ANSI_N ]='N';
+ g_keycodeCharShifted[ kVK_ANSI_M ]='M';
+ g_keycodeCharShifted[ kVK_ANSI_Period ]='>';
+ g_keycodeCharShifted[ kVK_ANSI_Grave ]='~';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-';
+ g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='=';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8';
+ g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9';
+ g_keycodeCharShifted[ kVK_Space ]=' ';
+}
+
+- (void)setupImGuiHooks
+{
+ ImGuiIO &io = ImGui::GetIO();
+
+ [self setupKeymaps];
+
+ // Account for retina display for glScissor
+ g_displayScale = [[UIScreen mainScreen] scale];
+
+ ImGuiStyle &style = ImGui::GetStyle();
+ style.TouchExtraPadding = ImVec2( 4.0, 4.0 );
+
+ io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists;
+
+ UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ];
+ [self.view addGestureRecognizer:panRecognizer];
+
+ UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)];
+ [self.view addGestureRecognizer:tapRecoginzer];
+
+ // Fill out the Synergy key map
+ // (for some reason synergy scan codes are off by 1)
+ io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1;
+ io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1;
+ io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1;
+ io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1;
+ io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1;
+ io.KeyMap[ImGuiKey_Home] = kVK_Home+1;
+ io.KeyMap[ImGuiKey_End] = kVK_End+1;
+ io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1;
+ io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1;
+ io.KeyMap[ImGuiKey_Enter] = kVK_Return+1;
+ io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1;
+ io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1;
+ io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1;
+ io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1;
+ io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1;
+ io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1;
+ io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1;
+}
+
+- (void)connectServer: (NSString*)serverName
+{
+ self.serverName = serverName;
+ g_serverName = serverName;
+
+ // Init synergy
+ NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey];
+
+ uSynergyInit( &_synergyCtx );
+ _synergyCtx.m_clientName = strdup( [bundleName UTF8String] );
+ _synergyCtx.m_clientWidth = self.view.bounds.size.width;
+ _synergyCtx.m_clientHeight = self.view.bounds.size.height;
+
+ _synergyCtx.m_connectFunc = ImGui_ConnectFunc;
+ _synergyCtx.m_sendFunc = ImGui_SendFunc;
+ _synergyCtx.m_receiveFunc = ImGui_RecvFunc;
+ _synergyCtx.m_sleepFunc = ImGui_SleepFunc;
+ _synergyCtx.m_traceFunc = ImGui_TraceFunc;
+ _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc;
+
+ _synergyCtx.m_traceFunc = ImGui_TraceFunc;
+ _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback;
+ _synergyCtx.m_mouseCallback = ImGui_MouseCallback;
+ _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback;
+
+ _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx;
+
+ // Create a background thread for synergy
+ _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL );
+ dispatch_async( _synergyQueue, ^{
+ while (1) {
+ uSynergyUpdate( &_synergyCtx );
+ }
+ });
+}
+
+
+- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer
+{
+
+ if ((recognizer.state == UIGestureRecognizerStateBegan) ||
+ (recognizer.state == UIGestureRecognizerStateChanged))
+ {
+ _mouseDown = YES;
+ _touchPos = [recognizer locationInView:self.view];
+ }
+ else
+ {
+ _mouseDown = NO;
+ _touchPos = CGPointMake( -1, -1 );
+ }
+}
+
+- (void)viewDidTap: (UITapGestureRecognizer*)recognizer
+{
+ _touchPos = [recognizer locationInView:self.view];
+ _mouseTapped = YES;
+}
+
+- (void)render
+{
+ ImGui::Render();
+}
+
+- (void)newFrame
+{
+ ImGuiIO& io = ImGui::GetIO();
+ ImGuiStyle &style = ImGui::GetStyle();
+
+ if (!g_FontTexture)
+ {
+ ImGui_ImplIOS_CreateDeviceObjects();
+ }
+
+ io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height );
+
+ io.MouseDrawCursor = g_synergyPtrActive;
+ if (g_synergyPtrActive)
+ {
+ style.TouchExtraPadding = ImVec2( 0.0, 0.0 );
+ io.MousePos = ImVec2( g_mousePosX, g_mousePosY );
+ for (int i=0; i < 3; i++)
+ {
+ io.MouseDown[i] = g_MousePressed[i];
+ }
+
+ // This is an arbitrary scaling factor that works for me. Not sure what units these
+ // mousewheel values from synergy are supposed to be in
+ io.MouseWheel = g_mouseWheelY / 500.0;
+ }
+ else
+ {
+ // Synergy not active, use touch events
+ style.TouchExtraPadding = ImVec2( 4.0, 4.0 );
+ io.MousePos = ImVec2(_touchPos.x, _touchPos.y );
+ if ((_mouseDown) || (_mouseTapped))
+ {
+ io.MouseDown[0] = true;
+ _mouseTapped = NO;
+ }
+ else
+ {
+ io.MouseDown[0] = false;
+ }
+ }
+
+ ImGui::NewFrame();
+}
+@end
+
+// 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)
+// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES
+static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data)
+{
+ // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled
+ GLint last_program, last_texture;
+ glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+ glEnable(GL_BLEND);
+ glBlendEquation(GL_FUNC_ADD);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_SCISSOR_TEST);
+ glActiveTexture(GL_TEXTURE0);
+
+ // Setup orthographic projection matrix
+ const float width = ImGui::GetIO().DisplaySize.x;
+ const float height = ImGui::GetIO().DisplaySize.y;
+ const float ortho_projection[4][4] =
+ {
+ { 2.0f/width, 0.0f, 0.0f, 0.0f },
+ { 0.0f, 2.0f/-height, 0.0f, 0.0f },
+ { 0.0f, 0.0f, -1.0f, 0.0f },
+ { -1.0f, 1.0f, 0.0f, 1.0f },
+ };
+ glUseProgram(g_ShaderHandle);
+ glUniform1i(g_AttribLocationTex, 0);
+ glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
+ glBindVertexArray(g_VaoHandle);
+
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
+ {
+ ImDrawList* cmd_list = draw_data->CmdLists[n];
+ ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front();
+
+ glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
+ const int needed_vtx_size = cmd_list->VtxBuffer.Size * sizeof(ImDrawVert);
+ if (g_VboSize < needed_vtx_size)
+ {
+ // Grow our buffer if needed
+ g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert);
+ glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW);
+ }
+
+ unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
+ if (!vtx_data)
+ continue;
+ memcpy(vtx_data, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
+ {
+ const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
+ if (pcmd->UserCallback)
+ {
+ pcmd->UserCallback(cmd_list, pcmd);
+ }
+ else
+ {
+ glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId);
+ glScissor((int)(pcmd->ClipRect.x * g_displayScale),
+ (int)((height - pcmd->ClipRect.w) * g_displayScale),
+ (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale),
+ (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale));
+ glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer );
+ }
+ idx_buffer += pcmd->ElemCount;
+ }
+ }
+
+ // Restore modified state
+ glBindVertexArray(0);
+ glBindBuffer( GL_ARRAY_BUFFER, 0);
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_DEPTH_TEST);
+ glUseProgram(last_program);
+ glDisable(GL_SCISSOR_TEST);
+ glBindTexture(GL_TEXTURE_2D, last_texture);
+}
+
+void ImGui_ImplIOS_CreateFontsTexture()
+{
+ // Build texture atlas
+ ImGuiIO& io = ImGui::GetIO();
+ unsigned char* pixels;
+ int width, height;
+ io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader.
+
+ // Upload texture to graphics system
+ GLint last_texture;
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+ glGenTextures(1, &g_FontTexture);
+ glBindTexture(GL_TEXTURE_2D, g_FontTexture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+
+ // Store our identifier
+ io.Fonts->TexID = (void *)(intptr_t)g_FontTexture;
+
+ // Restore state
+ glBindTexture(GL_TEXTURE_2D, last_texture);
+}
+
+bool ImGui_ImplIOS_CreateDeviceObjects()
+{
+ const GLchar *vertex_shader =
+ "uniform mat4 ProjMtx;\n"
+ "attribute highp vec2 Position;\n"
+ "attribute highp vec2 UV;\n"
+ "attribute highp vec4 Color;\n"
+ "varying vec2 Frag_UV;\n"
+ "varying vec4 Frag_Color;\n"
+ "void main()\n"
+ "{\n"
+ " Frag_UV = UV;\n"
+ " Frag_Color = Color;\n"
+ " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
+ "}\n";
+
+ const GLchar* fragment_shader =
+ "uniform sampler2D Texture;\n"
+ "varying highp vec2 Frag_UV;\n"
+ "varying highp vec4 Frag_Color;\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n"
+ "}\n";
+
+ g_ShaderHandle = glCreateProgram();
+ g_VertHandle = glCreateShader(GL_VERTEX_SHADER);
+ g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER);
+ glShaderSource(g_VertHandle, 1, &vertex_shader, 0);
+ glShaderSource(g_FragHandle, 1, &fragment_shader, 0);
+ glCompileShader(g_VertHandle);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log);
+ NSLog(@"VERTEX Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glCompileShader(g_FragHandle);
+
+#if defined(DEBUG)
+ glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *)malloc(logLength);
+ glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log);
+ NSLog(@"FRAGMENT Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glAttachShader(g_ShaderHandle, g_VertHandle);
+ glAttachShader(g_ShaderHandle, g_FragHandle);
+ glLinkProgram(g_ShaderHandle);
+
+ g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture");
+ g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx");
+ g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position");
+ g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV");
+ g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color");
+
+ glGenBuffers(1, &g_VboHandle);
+
+ glGenVertexArrays(1, &g_VaoHandle);
+ glBindVertexArray(g_VaoHandle);
+ glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
+ glEnableVertexAttribArray(g_AttribLocationPosition);
+ glEnableVertexAttribArray(g_AttribLocationUV);
+ glEnableVertexAttribArray(g_AttribLocationColor);
+
+#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
+ glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos));
+ glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv));
+ glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col));
+#undef OFFSETOF
+ glBindVertexArray(0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ ImGui_ImplIOS_CreateFontsTexture();
+
+ return true;
+}
diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m
new file mode 100644
index 0000000..faba099
--- /dev/null
+++ b/examples/apple_example/imguiex-ios/main.m
@@ -0,0 +1,13 @@
+//
+// main.m
+// imguiex
+//
+
+#import