> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/ocornut/imgui/llms.txt
> Use this file to discover all available pages before exploring further.

# Main Loop Functions

> Core functions for the Dear ImGui render loop

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

```cpp theme={null}
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.

```cpp theme={null}
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

```cpp theme={null}
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);
    }
}
```

<Note>
  Always call your backend's `NewFrame()` functions (e.g., `ImGui_ImplGlfw_NewFrame()`) before calling `ImGui::NewFrame()`.
</Note>

## EndFrame

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

```cpp theme={null}
void EndFrame();
```

### Description

This function:

* Finalizes the current frame's state
* Updates window positions and sizes
* Handles end-of-frame operations

<Warning>
  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.
</Warning>

### Example

```cpp theme={null}
// 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.

```cpp theme={null}
void Render();
```

### Description

This function:

* Calls `EndFrame()` internally
* Finalizes all draw lists
* Prepares `ImDrawData` for rendering
* Sorts draw commands by texture and layer

### Example

```cpp theme={null}
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();
```

<Note>
  You must call `Render()` before calling `GetDrawData()`. The draw data is only valid after finalization.
</Note>

## GetDrawData

Retrieves the draw data generated by the current frame. Pass this to your rendering backend.

```cpp theme={null}
ImDrawData* GetDrawData();
```

### Returns

<ResponseField name="return" type="ImDrawData*">
  Pointer to the draw data structure containing all draw commands for the frame. Returns NULL if `Render()` hasn't been called yet.
</ResponseField>

### 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

```cpp theme={null}
// 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

```cpp theme={null}
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);
    }
}
```

<Warning>
  The draw data is only valid until the next call to `NewFrame()`. Don't cache this pointer across frames.
</Warning>

## Complete Example

```cpp theme={null}
#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;
}
```
