// Poll events (platform-specific)glfwPollEvents();// Start the Dear ImGui frameImGui_ImplOpenGL3_NewFrame();ImGui_ImplGlfw_NewFrame();ImGui::NewFrame();
5
Submit UI code
Anywhere in your main loop after NewFrame():
// Your UI code hereImGui::Begin("Debug Window");ImGui::Text("FPS: %.1f", ImGui::GetIO().Framerate);ImGui::End();// Optional: show demo for learningImGui::ShowDemoWindow();
6
Render Dear ImGui
At the end of your frame, after your rendering:
// Finalize Dear ImGui frameImGui::Render();// Render your applicationglClear(GL_COLOR_BUFFER_BIT);RenderYourApplication();// Render Dear ImGui on topImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());// Swap buffersglfwSwapBuffers(window);
// After creating D3D11 device and windowIMGUI_CHECKVERSION();ImGui::CreateContext();ImGui_ImplWin32_Init(hwnd);ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext);// Main loopMSG msg;while (msg.message != WM_QUIT) { if (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); continue; } ImGui_ImplDX11_NewFrame(); ImGui_ImplWin32_NewFrame(); ImGui::NewFrame(); // Your UI code ImGui::Render(); const float clear_color[4] = { 0.1f, 0.1f, 0.1f, 1.0f }; g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, clear_color); ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); g_pSwapChain->Present(1, 0);}// CleanupImGui_ImplDX11_Shutdown();ImGui_ImplWin32_Shutdown();ImGui::DestroyContext();
// After creating D3D12 device and command queueIMGUI_CHECKVERSION();ImGui::CreateContext();ImGui_ImplWin32_Init(hwnd);ImGui_ImplDX12_Init(g_pd3dDevice, NUM_FRAMES_IN_FLIGHT, DXGI_FORMAT_R8G8B8A8_UNORM, g_pd3dSrvDescHeap, g_pd3dSrvDescHeap->GetCPUDescriptorHandleForHeapStart(), g_pd3dSrvDescHeap->GetGPUDescriptorHandleForHeapStart());// Main loop - similar to DX11 but with command lists// See examples/example_win32_directx12/ for full code// CleanupImGui_ImplDX12_Shutdown();ImGui_ImplWin32_Shutdown();ImGui::DestroyContext();
Dear ImGui needs to know when to capture input. Use these flags:
ImGuiIO& io = ImGui::GetIO();// Check if Dear ImGui wants keyboard inputif (!io.WantCaptureKeyboard) { // Pass keyboard events to your application}// Check if Dear ImGui wants mouse inputif (!io.WantCaptureMouse) { // Pass mouse events to your application}// Check if Dear ImGui wants text inputif (!io.WantTextInput) { // Your application logic}
Important: When io.WantCaptureMouse is true, don’t dispatch mouse input to your application. Similarly for keyboard. This prevents UI interactions from “falling through” to your application.
Dear ImGui embeds a default font, but you can load custom fonts:
ImGuiIO& io = ImGui::GetIO();// Add default font at different sizeio.Fonts->AddFontDefault();// Load TTF font from fileImFont* font = io.Fonts->AddFontFromFileTTF("fonts/Roboto-Regular.ttf", 16.0f);// Load with custom glyph ranges (for international text)ImFontConfig config;config.MergeMode = true;io.Fonts->AddFontFromFileTTF("fonts/DroidSans.ttf", 16.0f, &config, io.Fonts->GetGlyphRangesJapanese());// Use the fontImGui::PushFont(font);ImGui::Text("Custom font text");ImGui::PopFont();
Load fonts before the first frame. After adding fonts, they’re automatically uploaded to the GPU by the renderer backend.
set(IMGUI_DIR ${CMAKE_CURRENT_SOURCE_DIR}/imgui)add_library(imgui STATIC ${IMGUI_DIR}/imgui.cpp ${IMGUI_DIR}/imgui_draw.cpp ${IMGUI_DIR}/imgui_tables.cpp ${IMGUI_DIR}/imgui_widgets.cpp ${IMGUI_DIR}/imgui_demo.cpp ${IMGUI_DIR}/backends/imgui_impl_glfw.cpp ${IMGUI_DIR}/backends/imgui_impl_opengl3.cpp)target_include_directories(imgui PUBLIC ${IMGUI_DIR} ${IMGUI_DIR}/backends)target_link_libraries(imgui PUBLIC glfw OpenGL::GL)# Link to your executabletarget_link_libraries(your_app PRIVATE imgui)