- Notifications
You must be signed in to change notification settings - Fork184
Dear ImGui backend for use with SFML
License
SFML/imgui-sfml
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Library which allows you to useDear ImGui withSFML
Based onthis repository with big improvements and changes.
Development is focused on version 3 in themaster branch.No more features are planned for the 2.x release series.
- SFML >= 3.0.0
- Dear ImGui >= 1.91.1, < 1.92.0
- The code is written in C++17 (SFML 3 uses C++17, Dear ImGui has started using C++11 since 2022)
- The code should be formatted viaClangFormat using
.clang-formatprovided in the root of this repository
- CMake tutorial which also shows how to use ImGui-SFML with FetchContent
- Example project which sets up ImGui-SFML with FetchContent
- Detailed tutorial on Elias Daler's blog
- Using ImGui with modern C++ and STL
- Thread on SFML forums. Feel free to ask your questions there.
It's highly recommended to use FetchContent or git submodules to get SFML and Dear ImGui into your build.
Seethis file - if you do something similar, you can then just link to ImGui-SFML as simply as:
target_link_libraries(gamePUBLIC ImGui-SFML::ImGui-SFML)
- DownloadImGui
- Add Dear ImGui folder to your include directories
- Add
imgui.cpp,imgui_widgets.cpp,imgui_draw.cppandimgui_tables.cppto your build/project - Copy the contents of
imconfig-SFML.hto yourimconfig.hfile. (to be able to castImVec2tosf::Vector2fand vice versa) - Add a folder which contains
imgui-SFML.hto your include directories - Add
imgui-SFML.cppto your build/project - Link OpenGL if you get linking errors
Not recommended, as they're not maintained officially. Tend to lag behind and stay on older versions.
Call
ImGui::SFML::Initand pass yoursf::Window+sf::RenderTargetorsf::RenderWindowthere. You can create your font atlas and pass the pointer in Init too, otherwise the default internal font atlas will be created for you. Do this for each window you want to draw ImGui on.For each iteration of a game loop:
Poll and process events:
while (constauto event = window.pollEvent()) {ImGui::SFML::ProcessEvent(window, *event); ...}
Call
ImGui::SFML::Update(window, deltaTime)wheredeltaTimeissf::Time. You can also passmousePositionanddisplaySizeyourself instead of passing the window.Call ImGui functions (
ImGui::Begin(),ImGui::Button(), etc.)Call
ImGui::EndFrameafter the lastImGui::Endin your update function, if you update more than once before rendering. (e.g. fixed delta game loops)Call
ImGui::SFML::Render(window)
Call
ImGui::SFML::Shutdown()afterwindow.close()has been called- Use
ImGui::SFML::Shutdown(window)overload if you have multiple windows. After it's called one of the current windows will become a current "global" window. CallSetCurrentWindowto explicitly set which window will be used as default.
- Use
If you only draw ImGui widgets without any SFML stuff, then you'll might need to call window.resetGLStates() before rendering anything. You only need to do it once.
See example filehere
#include"imgui.h"#include"imgui-SFML.h"#include<SFML/Graphics/CircleShape.hpp>#include<SFML/Graphics/RenderWindow.hpp>#include<SFML/System/Clock.hpp>#include<SFML/Window/Event.hpp>intmain() { sf::RenderWindowwindow(sf::VideoMode({640,480}),"ImGui + SFML = <3"); window.setFramerateLimit(60);ImGui::SFML::Init(window); sf::CircleShapeshape(100.f); shape.setFillColor(sf::Color::Green); sf::Clock deltaClock;while (window.isOpen()) {while (constauto event = window.pollEvent()) {ImGui::SFML::ProcessEvent(window, *event);if (event->is<sf::Event::Closed>()) { window.close(); } }ImGui::SFML::Update(window, deltaClock.restart());ImGui::ShowDemoWindow();ImGui::Begin("Hello, world!");ImGui::Button("Look at this pretty button");ImGui::End(); window.clear(); window.draw(shape);ImGui::SFML::Render(window); window.display(); }ImGui::SFML::Shutdown();}
Default font is loaded if you don't passfalse inImGui::SFML::Init. CallImGui::SFML::Init(window, false); if you don't want default font to be loaded.
- Load your fonts like this:
IO.Fonts->Clear();// clear fonts if you loaded some before (even if only default one was loaded)// IO.Fonts->AddFontDefault(); // this will load default font as wellIO.Fonts->AddFontFromFileTTF("font1.ttf",8.f);IO.Fonts->AddFontFromFileTTF("font2.ttf",12.f);ImGui::SFML::UpdateFontTexture();// important call: updates font texture
- And use them like this:
ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[0]);ImGui::Button("Look at this pretty button");ImGui::PopFont();ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]);ImGui::TextUnformatted("IT WORKS!");ImGui::PopFont();
The first loaded font is treated as the default one and doesn't need to be pushed withImGui::PushFont.
Seeexamples/multiple_windows to see how you can create multiple SFML and run different ImGui contexts in them.
- Don't forget to run
ImGui::SFML::Init(const sf::Window&)for each window you create. Same goes forImGui::SFML::Shutdown(const sf::Window&) - Instead of calling
ImGui::SFML::ProcessEvent(sf::Event&), you need to callImGui::SFML::ProcessEvent(const sf::Window&, const sf::Event&)overload for each window you create - Call
ImGui::SFML::SetCurrentWindowbefore calling anyImGuifunctions (e.g.ImGui::Begin,ImGui::Buttonetc.) - Either call
ImGui::Render(sf::RenderWindow&)overload for each window or manually do this:SetCurrentWindow(window);...// your custom renderingImGui::Render();SetCurrentWindow(window2);...// your custom renderingImGui::Render();
- When closing everything: don't forget to close all windows using SFML's
sf::Window::Closeand then callImGui::SFML::Shutdownto remote all ImGui-SFML window contexts and other data.
There are some useful overloads implemented for SFML objects (seeimgui-SFML.h for other overloads):
ImGui::Image(const sf::Sprite& sprite);ImGui::Image(const sf::Texture& texture);ImGui::Image(const sf::RenderTexture& texture);ImGui::ImageButton(const sf::Sprite& sprite);ImGui::ImageButton(const sf::Texture& texture);ImGui::ImageButton(const sf::RenderTexture& texture);
sf::RenderTexture's texture is stored with pixels flipped upside down. To display it properly when drawingImGui::Image orImGui::ImageButton, use overloads forsf::RenderTexture:
sf::RenderTexture texture;sf::Spritesprite(texture.getTexture());ImGui::Image(texture);// OKImGui::Image(sprite);// NOT OKImGui::Image(texture.getTexture());// NOT OK
If you want to draw only a part ofsf::RenderTexture and you're trying to usesf::Sprite the texture will be displayed upside-down. To prevent this, you can do this:
// make a normal sf::Texture from sf::RenderTexture's flipped texturesf::Texturetexture(renderTexture.getTexture());sf::Spritesprite(texture);ImGui::Image(sprite);// the texture is displayed properly
For more notes seethis issue.
You can change your cursors in ImGui like this:
ImGui::SetMouseCursor(ImGuiMouseCursor_TextInput);By default, your system cursor will change and will be rendered by your system. If you want SFML to draw your cursor with default ImGui cursors (the system cursor will be hidden), do this:
ImGuiIO& io = ImGui::GetIO();io.MouseDrawCursor =true;Starting withImGui 1.60, there's a feature to control ImGui with keyboard and gamepad. To use keyboard navigation, you just need to do this:
ImGuiIO& io = ImGui::GetIO();io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
Gamepad navigation requires more work, unless you have XInput gamepad, in which case the mapping is automatically set for you. But you can still set it up for your own gamepad easily, just take a look how it's done for the default mappinghere. And then you need to do this:
ImGuiIO& io = ImGui::GetIO();io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
By default, the first active joystick is used for navigation, but you can set joystick id explicitly like this:
ImGui::SFML::SetActiveJoystickId(5);
As SFML is not currently DPI aware, your GUI may show at the incorrect scale. This is particularly noticeable on systems with "Retina" / "4K" / "UHD" displays.
To work around this on macOS, you can create an app bundle (as opposed to just the exe) then modify the info.plist so that "High Resolution Capable" is set to "NO".
Another option to help ameliorate this, at least for getting started and for the common ImGui use-case of "developer/debug/building UI", is to exploreFontGlobalScale:
ImGuiIO& io = ImGui::GetIO();io.FontGlobalScale =2.0;// or any other value hardcoded or loaded from your config logic
This library is licensed under the MIT License, see LICENSE for more information.
About
Dear ImGui backend for use with SFML
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Uh oh!
There was an error while loading.Please reload this page.
