Skip to main content
These functions form the backbone of the Dear ImGui render loop. Call them in sequence each frame to process input, build your UI, and generate draw commands for rendering.

Frame Lifecycle

The typical Dear ImGui frame consists of:
  1. NewFrame() - Start a new frame, process input
  2. UI Code - Build your user interface
  3. Render() - Finalize draw data
  4. GetDrawData() - Retrieve draw commands
  5. Backend Rendering - Submit to graphics API
while (running) {
    ImGui::NewFrame();
    
    // Your UI code here
    ImGui::Begin("My Window");
    ImGui::Text("Hello, world!");
    ImGui::End();
    
    ImGui::Render();
    ImGui_ImplXXX_RenderDrawData(ImGui::GetDrawData());
}

NewFrame

Starts a new Dear ImGui frame. Call this at the beginning of each frame before submitting any UI commands.
void NewFrame();

Description

This function:
  • Processes input from ImGuiIO (mouse, keyboard, gamepad)
  • Updates internal state and timing
  • Prepares for new UI commands
  • Clears the previous frame’s data

Example

void GameLoop() {
    while (!glfwWindowShouldClose(window)) {
        // Poll events and update ImGui backends
        glfwPollEvents();
        ImGui_ImplGlfw_NewFrame();
        ImGui_ImplOpenGL3_NewFrame();
        
        // Start Dear ImGui frame
        ImGui::NewFrame();
        
        // Build UI
        ImGui::ShowDemoWindow();
        
        // Render
        ImGui::Render();
        glClear(GL_COLOR_BUFFER_BIT);
        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
        glfwSwapBuffers(window);
    }
}
Always call your backend’s NewFrame() functions (e.g., ImGui_ImplGlfw_NewFrame()) before calling ImGui::NewFrame().

EndFrame

Ends the Dear ImGui frame. Automatically called by Render(), but can be called manually if you want to skip rendering.
void EndFrame();

Description

This function:
  • Finalizes the current frame’s state
  • Updates window positions and sizes
  • Handles end-of-frame operations
If you call EndFrame() without rendering, you’ll waste CPU cycles. It’s better to not create any windows and skip NewFrame() entirely if you don’t need to render.

Example

// Skip rendering when window is minimized
if (isMinimized) {
    ImGui::NewFrame();
    ImGui::EndFrame();
    // Don't call Render() or GetDrawData()
} else {
    ImGui::NewFrame();
    // ... UI code ...
    ImGui::Render();
    ImGui_ImplXXX_RenderDrawData(ImGui::GetDrawData());
}

Render

Ends the Dear ImGui frame and finalizes draw data. Call this after submitting all UI commands.
void Render();

Description

This function:
  • Calls EndFrame() internally
  • Finalizes all draw lists
  • Prepares ImDrawData for rendering
  • Sorts draw commands by texture and layer

Example

ImGui::NewFrame();

// Build your UI
ImGui::Begin("Control Panel");
ImGui::Button("Click Me");
ImGui::End();

ImGui::Begin("Debug Info");
ImGui::Text("FPS: %.1f", ImGui::GetIO().Framerate);
ImGui::End();

// Finalize frame
ImGui::Render();

// Now you can retrieve draw data
ImDrawData* draw_data = ImGui::GetDrawData();
You must call Render() before calling GetDrawData(). The draw data is only valid after finalization.

GetDrawData

Retrieves the draw data generated by the current frame. Pass this to your rendering backend.
ImDrawData* GetDrawData();

Returns

return
ImDrawData*
Pointer to the draw data structure containing all draw commands for the frame. Returns NULL if Render() hasn’t been called yet.

Description

The returned ImDrawData contains:
  • All draw commands organized by command lists
  • Vertex and index buffers
  • Texture bindings
  • Clipping rectangles
  • Display position and size

Example

// After calling Render()
ImDrawData* draw_data = ImGui::GetDrawData();

if (draw_data != nullptr) {
    // Pass to your rendering backend
    ImGui_ImplOpenGL3_RenderDrawData(draw_data);
    // or
    ImGui_ImplDX11_RenderDrawData(draw_data);
    // or
    ImGui_ImplVulkan_RenderDrawData(draw_data);
}

Validation

ImDrawData* draw_data = ImGui::GetDrawData();

if (draw_data && draw_data->Valid) {
    printf("Total draw commands: %d\n", draw_data->TotalVtxCount);
    printf("Display size: %.0fx%.0f\n", 
           draw_data->DisplaySize.x, 
           draw_data->DisplaySize.y);
    
    for (int n = 0; n < draw_data->CmdListsCount; n++) {
        const ImDrawList* cmd_list = draw_data->CmdLists[n];
        printf("Command list %d: %d vertices, %d indices\n",
               n, cmd_list->VtxBuffer.Size, cmd_list->IdxBuffer.Size);
    }
}
The draw data is only valid until the next call to NewFrame(). Don’t cache this pointer across frames.

Complete Example

#include "imgui.h"
#include "imgui_impl_glfw.h"
#include "imgui_impl_opengl3.h"
#include <GLFW/glfw3.h>

int main() {
    // Initialize GLFW and OpenGL
    glfwInit();
    GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui Example", NULL, NULL);
    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);
    
    // Setup Dear ImGui context
    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGuiIO& io = ImGui::GetIO();
    
    // Setup backends
    ImGui_ImplGlfw_InitForOpenGL(window, true);
    ImGui_ImplOpenGL3_Init("#version 130");
    
    // Main loop
    while (!glfwWindowShouldClose(window)) {
        glfwPollEvents();
        
        // Start ImGui frame
        ImGui_ImplOpenGL3_NewFrame();
        ImGui_ImplGlfw_NewFrame();
        ImGui::NewFrame();
        
        // Build UI
        ImGui::Begin("Hello, ImGui!");
        ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 
                    1000.0f / io.Framerate, io.Framerate);
        ImGui::End();
        
        // Render
        ImGui::Render();
        int display_w, display_h;
        glfwGetFramebufferSize(window, &display_w, &display_h);
        glViewport(0, 0, display_w, display_h);
        glClearColor(0.45f, 0.55f, 0.60f, 1.00f);
        glClear(GL_COLOR_BUFFER_BIT);
        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
        
        glfwSwapBuffers(window);
    }
    
    // Cleanup
    ImGui_ImplOpenGL3_Shutdown();
    ImGui_ImplGlfw_Shutdown();
    ImGui::DestroyContext();
    glfwDestroyWindow(window);
    glfwTerminate();
    
    return 0;
}

Build docs developers (and LLMs) love