Реализуем функцию сложения: два поля для ввода чисел, знак плюс между ними и кнопка равно. После ввода двух цифр и нажатия на = результат вычисления отобразится в третьем поле ввода.
Функционал очень простой, но на этом примере мы познакомимся с основными элементами форм ImGui.
Сначала посмотрите скриншот работающей программы

Это минималистичный пример. Большая часть кода повторяет урок из предыдущего занятия, отличается только блок отрисовки интерфейса. Также мы добавили переменные для хранения числовых значений и переключили тему на светлую — так интерфейс больше похож на обычные настольные GUI-программы.
#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup")
#include <GLFW/glfw3.h>
#include "imgui.h"
#include "backends/imgui_impl_glfw.h"
#include "backends/imgui_impl_opengl3.h"
#include <cstdio>
int main()
{
if (!glfwInit())
{
printf("Ошибка инициализации GLFW\n");
return -1;
}
const char* glsl_version = "#version 330";
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(500, 200, "Калькулятор сложения", nullptr, nullptr); // Размер и заголовок окна
if (!window)
{
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
ImGui::StyleColorsLight(); // Включить светлую цветовую тему
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init(glsl_version);
// Глобальные переменные калькулятора
float num1 = 0.0f; // Первое слагаемое
float num2 = 0.0f; // Второе слагаемое
float result = 0.0f; // Сумма двух чисел
while (!glfwWindowShouldClose(window))
{
glfwPollEvents();
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
ImGui::SetNextWindowPos(ImVec2(0, 0));
ImGui::SetNextWindowSize(io.DisplaySize);
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDecoration
| ImGuiWindowFlags_NoMove
| ImGuiWindowFlags_NoResize
| ImGuiWindowFlags_NoSavedSettings;
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
ImGui::Begin("Панель управления", nullptr, window_flags);
// Заголовок калькулятора
ImGui::Text("Введите два числа"); // Статический текст, занимает всю строку
ImGui::Spacing();// Добавить вертикальный отступ
// Первое поле ввода чисел, ширина 120 пикселей
ImGui::SetNextItemWidth(120);// Устанавливает ширину следующего виджета, сам ничего не рисует
ImGui::InputFloat("##num1", &num1);// Поле ввода дробных чисел, привязано к num1, скрытая подпись, отдельная строка
// Отрисовать знак плюс на той же строке
ImGui::SameLine(); // Следующий элемент рисуется в той же строке; без этого будет автоматический переход на новую строку
ImGui::Text(" + "); // Знак плюс рядом с первым полем ввода
// Второе поле ввода чисел
ImGui::SameLine(); // Вызывать перед каждым элементом, который нужно расположить горизонтально
ImGui::SetNextItemWidth(120);// Установить ширину второго поля ввода
ImGui::InputFloat("##num2", &num2);
// Кнопка равно, запускает вычисление суммы при клике
ImGui::SameLine();
if (ImGui::Button(" = ", ImVec2(40, 0)))
{
// Вычислить сумму и сохранить в переменную результата
result = num1 + num2;
}
// Поле результата только для чтения, вывод с двумя знаками после запятой, ручное редактирование запрещено
ImGui::SameLine();
ImGui::SetNextItemWidth(180);
ImGui::InputFloat("##result", &result, 0.0f, 0.0f, "%.2f", ImGuiInputTextFlags_ReadOnly);
ImGui::End();
// Вернуть сохранённые стили по умолчанию
ImGui::PopStyleVar(2);
ImGui::Render();
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
glClearColor(0.12f, 0.12f, 0.12f, 1.f);
glClear(GL_COLOR_BUFFER_BIT);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
glfwSwapBuffers(window);
}
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}Code language: C++ (cpp)
Чтобы включить светлую тему, достаточно изменить одну строку: ImGui::StyleColorsLight(); // Переключить интерфейс на светлую цветовую схему
Для изменения заголовка и размеров окна редактируйте эту строку: GLFWwindow* window = glfwCreateWindow(400, 60, «Калькулятор сложения», nullptr, nullptr); // Задаёт ширину, высоту и текст заголовка окна
ImGui::Text("Введите два числа");
ImGui::Spacing(); // Создать вертикальный отступ между заголовком и полями ввода нижеCode language: PHP (php)
Эта строка выводит статический текст в первую строку, затем добавляет вертикальный промежуток на следующей строке.
Остальные свойства виджетов смотрите в комментариях выше. По умолчанию Text, InputFloat и Button каждый занимают отдельную строку. Если не нужно переносить строку, перед отрисовкой каждого горизонтального элемента вызовите ImGui::SameLine();.
Чтобы задать ширину следующего элемента интерфейса вручную, используйте функцию SetNextItemWidth().
Принцип работы клика по кнопке
if (ImGui::Button(" = ", ImVec2(40, 0)))
{
// Вычислить сумму двух чисел и присвоить результат переменной
result = num1 + num2;
}Code language: C++ (cpp)
В данном фрагменте ImGui::Button(» = «, ImVec2(40, 0)) рисует интерактивную кнопку. Первый аргумент — надпись на кнопке, второй задаёт её ширину и высоту; при высоте 0 размер подстраивается автоматически под стандарт виджета.
Функция возвращает true только при полном клике (нажатие и отпускание мыши над областью кнопки), во всех остальных случаях возвращается false. Если возвращается true, выполняется весь код внутри фигурных скобок {}.
Представьте этот процесс как непрерывный цикл отрисовки: интерфейс обновляется каждый кадр, весь код внутри while запускается при каждом обновлении. Если пользователь не совершает никаких действий, каждый кадр выглядит одинаково. Если в какой-то момент нажимается кнопка, ImGui::Button() вернёт true и запустит логику вычисления.
Код внутри кнопки складывает значения, привязанные к двум полям ввода, сохраняет сумму в переменную result, после чего рисует поле вывода на той же строке.
ImGui::SameLine();
ImGui::SetNextItemWidth(180);
ImGui::InputFloat("##result", &result, 0.0f, 0.0f, "%.2f", ImGuiInputTextFlags_ReadOnly);Code language: C++ (cpp)
Этот код остаётся на одной строке с кнопкой равно и отображает вычисленную сумму в третьем поле ввода, которое настроено только для чтения.
После завершения отрисовки одного кадра при следующем обновлении предыдущий результат сохранится, если пользователь не произведёт новых действий.
Механизм отрисовки полностью повторяет логику видеоигр; игровые анимации работают по такому же принципу постоянного обновления кадров.