Hi, Habr!
This article is a free translation of my article into Russian with some minor changes and improvements. I would like to show how simple and useful to use ImGui with SFML. Let's get started
When developing games it is very important to have good tools for creating content (editor of levels, resources, etc.), as well as for debugging. The presence of these things increases productivity and creativity. It is much easier to catch bugs and fix those already found: it is easy to display the value of various variables, as well as create widgets to change them, to see what happens with the game for certain values. Variable change widgets are also very useful for polishing gameplay. For example, you can easily change the speed of movement of characters, the speed of reloading weapons, etc.
Here are the tools I created using ImGui for my game :
Level editor
Lua console
Animation editor
As you can see, ImGui has enough different widgets to create useful and convenient interfaces.
Immediate mode GUI is slightly different from the classical interface programming technique called retained mode GUI . ImGui widgets are created and drawn in each frame of the game cycle. Widgets themselves do not store their state inside themselves, or they store an absolutely minimum necessary minimum, which is usually hidden from the programmer.
Unlike Qt, where to create a button you need to create a QPushButton
object, and then associate with it any callback function called when pressed, everything in ImGui is much easier. In the code it is enough to write:
if (ImGui::Button("Some Button")) { ... // , }
This code should be called at each iteration of the game cycle, in which this button should be available to the user.
Initially, this concept may seem strange and very inefficient, but it all works so quickly compared to the rest of the code that, as a result, even complex interfaces do not introduce major changes in game performance.
I advise you to watch this Casey Muratori video about ImGui if you want to know a little more about this technique.
So what are the benefits of ImGui?
So, let's begin
Add the following files to your project build:
Here is a small example of the code that creates the ImGui window and allows you to change the background color and title of the window. Explanations of what is happening will be further.
#include "imgui.h" #include "imgui-sfml.h" #include <SFML/Graphics/RenderWindow.hpp> #include <SFML/System/Clock.hpp> #include <SFML/Window/Event.hpp> int main() { sf::RenderWindow window(sf::VideoMode(640, 480), ""); window.setVerticalSyncEnabled(true); ImGui::SFML::Init(window); sf::Color bgColor; float color[3] = { 0.f, 0.f, 0.f }; // char. // std::string , char windowTitle[255] = "ImGui + SFML = <3"; window.setTitle(windowTitle); sf::Clock deltaClock; while (window.isOpen()) { sf::Event event; while (window.pollEvent(event)) { ImGui::SFML::ProcessEvent(event); if (event.type == sf::Event::Closed) { window.close(); } } ImGui::SFML::Update(window, deltaClock.restart()); ImGui::Begin("Sample window"); // // if (ImGui::ColorEdit3("Background color", color)) { // , // bgColor.r = static_cast<sf::Uint8>(color[0] * 255.f); bgColor.g = static_cast<sf::Uint8>(color[1] * 255.f); bgColor.b = static_cast<sf::Uint8>(color[2] * 255.f); } ImGui::InputText("Window title", windowTitle, 255); if (ImGui::Button("Update window title")) { // , // // if(ImGui::InputText(...)) window.setTitle(windowTitle); } ImGui::End(); // end window window.clear(bgColor); // ImGui::SFML::Render(window); window.display(); } ImGui::SFML::Shutdown(); }
You should see something like this:
Try changing something. If you double-click on one of the RGB fields, you can enter the corresponding value. If you pull one of the fields, you can smoothly change the current value entered. The input field allows you to change the window title after clicking on the button.
Ok, now let's figure out how everything works.
ImGui is initialized by calling ImGui::SFML::Init
, when calling the function, a link to the sf::RenderWindow
window is sf::RenderWindow
. At this point, a standard font is also created, which will be used later. (See the Fonts how-to section for a description of imgui-sfml to see how to use other fonts.)
When you exit the program, it is important to call the ImGui::SFML::Shutdown
function, which frees the resources ImGui uses.
In the game cycle ImGui has two phases: update and rendering.
The update consists of event handling, updating ImGui status and updating / creating widgets. Event handling occurs through a call to ImGui::SFML::ProcessEvent
. ImGui handles keyboard, mouse, focus and window size events. ImGui state is updated in ImGui::SFML::Update
, it is transferred to the delta time (time between two updates), which ImGui uses to update the state of widgets (for example, for animation). Also in this function ImGui::NewFrame
, after calling which new widgets can already be created.
ImGui is rendered by calling ImGui::SFML::Render
. It is very important to create / update widgets between calls ImGui::SFML::Update
and ImGui::SFML::Render
, otherwise ImGui will swear at a state violation.
If you render less often than update input and play, then at the end of each iteration of your update
you must also call ImGui::EndFrame
:
while (gameIsRunning) { while (updateIsNeeded()) { updateGame(dt); ImGui::SFML::Update(window, dt); ImGui::EndFrame(); } renderGame(); }
Widgets are created by calling the appropriate functions (for example, ImGui::InputInt
or ImGui::Button
). If you call ImGui::ShowTestWindow
, you can see many examples of using ImGui, all the code can be found in imgui_demo.cpp .
For SFML, some overloading of functions was created in the binding, for example, in ImGui::Image
and ImGui::ImageButton
you can throw sf::Sprite
and sf::Texture
, you can also easily draw lines and rectangles by calling DrawLine
, DrawRect
and DrawRectFilled
.
Here is a library: easy to use and configure, and very useful for creating tools and debugging. Enjoy using!
PS If there is interest, I can translate the second part of the tutorial , which tells about the use of ImGui with modern C ++ and the standard library. I advise you to draw attention to the article for those who decide to use (or are already using) ImGui: it shows how easy it is to solve the main problems of ImGui and make everything easier and safer than it is done in C ++ 03.
Source: https://habr.com/ru/post/335512/
All Articles