實作加法運算功能,畫面包含兩個輸入框、中間加號、一個等號按鈕。輸入兩組數字後點擊=,計算結果會顯示在第三個輸入欄位。
範例功能雖然簡單,但透過這個專案,就能認識ImGui基礎表單元件的使用方式。
先看執行後的畫面截圖

這是超精簡範例,整體程式碼大部分跟上一堂課範例幾乎相同,僅有UI繪製區段邏輯有差異,另外新增幾個儲存數值的變數;同時主題切換成淺色風格,視覺上更貼近一般常見的桌面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內的程式;如果使用者沒有任何操作,每一次繪製的畫面都會完全相同。只要某一幀使用者點擊按鈕,繪製該按鈕時就會回傳true,接著執行按鈕內的運算程式。
按鈕內的邏輯會讀取兩個輸入框綁定的數值、計算總和後存入result變數,接著繪製同列的結果輸入欄。
ImGui::SameLine();
ImGui::SetNextItemWidth(180);
ImGui::InputFloat("##result", &result, 0.0f, 0.0f, "%.2f", ImGuiInputTextFlags_ReadOnly);Code language: C++ (cpp)
這段程式維持與按鈕同一列,並將剛計算完成的result數值顯示在第三個輸入框,此欄位設為唯讀無法手動編輯。
完成單次畫面刷新後,下一幀若使用者無新操作,依舊會顯示上一次運算的結果。
這個繪製邏輯和遊戲的渲染架構完全相同,遊戲動畫也是使用這種持續刷新畫面的機制實現。