Einfachen Additionsrechner mit ImGui erstellen

Wir erstellen eine Additionsfunktion mit zwei Eingabefeldern für Zahlen, einem Pluszeichen dazwischen und einem Gleichheitsbutton. Gibst du zwei Zahlen ein und klickst auf =, wird das Ergebnis im dritten Eingabefeld angezeigt.

Die Funktionalität ist simpel, aber an diesem Beispiel lernen wir die grundlegenden Formular-Widgets von ImGui kennen.

Zuerst sehen wir einen Screenshot des laufenden Programms

Dies ist ein sehr kompaktes Beispiel. Der Großteil des Codes stimmt mit dem Beispiel aus der vorherigen Lektion überein, nur der UI-Rendering-Teil unterscheidet sich. Zusätzlich haben wir Variablen zur Speicherung der Zahlenwerte hinzugefügt und das Design auf helles Theme umgestellt – das sieht herkömmlichen Desktop-GUI-Programmen ähnlicher.

#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 Initialisierung fehlgeschlagen\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, "Additionsrechner", nullptr, nullptr); // Fenstergröße und Titel
    if (!window)
    {
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);

    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGuiIO& io = ImGui::GetIO();
	ImGui::StyleColorsLight(); // Helles Design aktivieren

    ImGui_ImplGlfw_InitForOpenGL(window, true);
    ImGui_ImplOpenGL3_Init(glsl_version);

    // Globale Variablen für den Additionsrechner
    float num1 = 0.0f;    // Erster Summand
    float num2 = 0.0f;    // Zweiter Summand
    float result = 0.0f;  // Ergebnis der Addition

    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("Steuerpanel", nullptr, window_flags);

        // Rechner-Überschrift
        ImGui::Text("Bitte gib zwei Zahlen ein"); // Statischer Text, belegt eine komplette Zeile
	ImGui::Spacing();// Vertikalen Abstand einfügen

        // Erstes Zahleneingabefeld, Breite 120 Pixel
	ImGui::SetNextItemWidth(120);// Legt Breite des folgenden Widgets fest, erzeugt keine eigene Anzeige
	ImGui::InputFloat("##num1", &num1);// Gleitkommaeingabe gebunden an num1, verstecktes Label, eigene Zeile

        // Pluszeichen auf derselben Zeile zeichnen
	ImGui::SameLine(); // Nächstes Widget auf gleicher Zeile; ohne diesen Aufruf erfolgt automatischer Zeilenumbruch
	ImGui::Text(" + "); // Pluszeichen auf gleicher Zeile wie erstes Eingabefeld

        // Zweites Zahleneingabefeld
	ImGui::SameLine(); // Muss vor jedem nebeneinanderliegenden Widget aufgerufen werden
        ImGui::SetNextItemWidth(120);// Breite des zweiten Eingabefelds festlegen
        ImGui::InputFloat("##num2", &num2);

        // Gleichheitsbutton, löst Addition bei Klick aus
        ImGui::SameLine();
        if (ImGui::Button(" = ", ImVec2(40, 0)))
        {
            // Summe berechnen und Ergebnisvariable zuweisen
            result = num1 + num2;
        }

        // Nur-lesbares Ergebnisfeld, Anzeige mit zwei Nachkommastellen, manuelle Bearbeitung gesperrt
        ImGui::SameLine();
        ImGui::SetNextItemWidth(180);
        ImGui::InputFloat("##result", &result, 0.0f, 0.0f, "%.2f", ImGuiInputTextFlags_ReadOnly);

        ImGui::End();

	// Gespeicherte Stilwerte wiederherstellen
        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-Sprache: C++ (cpp)

Um das helle Design zu aktivieren, ändere einfach diese Zeile: ImGui::StyleColorsLight(); // Schaltet das UI auf helles Farbdesign um

Fenstertitel und Größe werden in dieser Zeile angepasst: GLFWwindow* window = glfwCreateWindow(400, 60, „Additionsrechner“, nullptr, nullptr); // Definiert Fensterbreite, Höhe und Titeltext

ImGui::Text("Bitte gib zwei Zahlen ein");

ImGui::Spacing(); // Vertikalen Abstand zwischen Überschrift und unteren Eingabefeldern einfügenCode-Sprache: PHP (php)

Diese Zeile gibt statischen Text in der ersten Zeile aus und fügt dann vertikalen Abstand in der nächsten Zeile ein.

Weitere Widget-Eigenschaften findest du in den obigen Code-Kommentaren. Standardmäßig belegen Text, InputFloat und Button jeweils eine eigene Zeile. Sollen Elemente nebeneinander stehen, rufe vor jedem folgenden Widget ImGui::SameLine(); auf – dann gibt es keinen Zeilenumbruch.

Mit SetNextItemWidth() legst du manuell die Breite des als Nächstes gerenderten UI-Elements fest.

Funktionsweise von Button-Klicks

if (ImGui::Button(" = ", ImVec2(40, 0)))
 {
            // Summe der beiden Eingabewerte berechnen und in Ergebnisvariable speichern
            result = num1 + num2;
 }Code-Sprache: C++ (cpp)

Im Code erzeugt ImGui::Button(“ = „, ImVec2(40, 0)) einen interaktiven Button. Der erste Parameter ist der angezeigte Text, der zweite gibt Breite und Höhe an; Höhe 0 bedeutet automatische Anpassung an die Standard-Widgethöhe.

Diese Funktion gibt nur dann true zurück, wenn du den Button vollständig klickst (Maus drücken + loslassen über dem Button-Bereich) – in allen anderen Fällen false. Bei Rückgabewert true wird der gesamte Code innerhalb der geschweiften Klammern {} ausgeführt.

Stell dir den Ablauf als dauernden Render-Loop vor: Die Oberfläche wird in jedem Frame neu gezeichnet, sämtlicher Code innerhalb der while-Schleife läuft bei jeder Aktualisierung. Wenn der Nutzer keine Eingabe tätigt, bleibt das Bild jedes Mal identisch. Klickt er in einem Frame den Button, gibt ImGui::Button() true zurück und der Berechnungscode wird ausgeführt.

Der Code im Button-Block addiert die an die Eingabefelder gebundenen Zahlen, speichert die Summe in result und rendert anschließend das Ergebnisfeld auf derselben Zeile.

ImGui::SameLine();
ImGui::SetNextItemWidth(180);
ImGui::InputFloat("##result", &result, 0.0f, 0.0f, "%.2f", ImGuiInputTextFlags_ReadOnly);Code-Sprache: C++ (cpp)

Dieser Code bleibt auf derselben Zeile wie der Gleichheitsbutton und zeigt den berechneten Wert im dritten Eingabefeld an, das als schreibgeschützt markiert ist.

Nach Abschluss eines Frame-Renderings wird im nächsten Refresh-Zyklus das vorherige Ergebnis angezeigt, solange keine neue Nutzeraktion stattfindet.

Dieser Render-Mechanismus ist identisch mit dem Ablauf bei Videospielen – auch Spielanimationen basieren auf diesem wiederholten Bildaufbau.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert