Overview
ImDrawList is the low-level list of polygons that ImGui functions are filling. At the end of each frame, all command lists are passed to your rendering function. You can use ImGui::GetWindowDrawList() to access the current window’s draw list and add custom primitives.
You can interleave normal ImGui calls and adding primitives to the current draw list.
Getting a Draw List
GetWindowDrawList
ImDrawList* GetWindowDrawList();
Get draw list associated to the current window, to append your own drawing primitives.
Pointer to the current window’s draw list
Example:
ImDrawList* draw_list = ImGui::GetWindowDrawList();
ImVec2 pos = ImGui::GetCursorScreenPos();
draw_list->AddCircleFilled(pos, 20.0f, IM_COL32(255, 0, 0, 255));
Structure
struct ImDrawList
{
ImVector<ImDrawCmd> CmdBuffer; // Draw commands
ImVector<ImDrawIdx> IdxBuffer; // Index buffer
ImVector<ImDrawVert> VtxBuffer; // Vertex buffer
ImDrawListFlags Flags; // Flags (anti-aliasing, etc.)
// ... internal members
};
Draw commands. Typically 1 command = 1 GPU draw call (unless it’s a callback).
Index buffer. Each command consumes ImDrawCmd::ElemCount of these.
Flags controlling anti-aliasing and other rendering options.
Clipping
PushClipRect
void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max,
bool intersect_with_current_clip_rect = false);
Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping.
Top-left corner of clipping rectangle
Bottom-right corner of clipping rectangle
intersect_with_current_clip_rect
If true, intersect with current clip rect instead of replacing it
Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling).
PopClipRect
Restore previous clipping rectangle.
PushClipRectFullScreen
void PushClipRectFullScreen();
Set clipping rectangle to full screen.
Texture Management
PushTexture
void PushTexture(ImTextureRef tex_ref);
Set texture for subsequent drawing commands.
PopTexture
Restore previous texture.
Primitive Shapes
Filled shapes must always use clockwise winding order. The anti-aliasing fringe depends on it. Counter-clockwise shapes will have “inward” anti-aliasing.
AddLine
void AddLine(const ImVec2& p1, const ImVec2& p2, ImU32 col, float thickness = 1.0f);
Draw a line between two points.
Color (use IM_COL32(r, g, b, a) macro)
Example:
ImDrawList* draw_list = ImGui::GetWindowDrawList();
ImVec2 p1 = ImGui::GetCursorScreenPos();
ImVec2 p2 = ImVec2(p1.x + 100, p1.y + 50);
draw_list->AddLine(p1, p2, IM_COL32(255, 255, 0, 255), 2.0f);
AddRect
void AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col,
float rounding = 0.0f, ImDrawFlags flags = 0, float thickness = 1.0f);
Draw a rectangle outline.
Flags for corner rounding (e.g., ImDrawFlags_RoundCornersTopLeft)
AddRectFilled
void AddRectFilled(const ImVec2& p_min, const ImVec2& p_max, ImU32 col,
float rounding = 0.0f, ImDrawFlags flags = 0);
Draw a filled rectangle.
Example:
ImVec2 p_min = ImGui::GetCursorScreenPos();
ImVec2 p_max = ImVec2(p_min.x + 100, p_min.y + 100);
draw_list->AddRectFilled(p_min, p_max, IM_COL32(0, 255, 0, 128), 10.0f);
AddRectFilledMultiColor
void AddRectFilledMultiColor(const ImVec2& p_min, const ImVec2& p_max,
ImU32 col_upr_left, ImU32 col_upr_right,
ImU32 col_bot_right, ImU32 col_bot_left);
Draw a filled rectangle with different colors at each corner (gradient).
Bottom-right corner color
AddQuad / AddQuadFilled
void AddQuad(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4,
ImU32 col, float thickness = 1.0f);
void AddQuadFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4,
ImU32 col);
Draw a quadrilateral (4-sided polygon).
AddTriangle / AddTriangleFilled
void AddTriangle(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3,
ImU32 col, float thickness = 1.0f);
void AddTriangleFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col);
Draw a triangle.
AddCircle / AddCircleFilled
void AddCircle(const ImVec2& center, float radius, ImU32 col,
int num_segments = 0, float thickness = 1.0f);
void AddCircleFilled(const ImVec2& center, float radius, ImU32 col, int num_segments = 0);
Draw a circle.
Number of segments (0 = auto-calculate based on radius)
Use num_segments = 0 to automatically calculate tessellation (preferred).
Example:
ImVec2 center = ImVec2(100, 100);
draw_list->AddCircleFilled(center, 30.0f, IM_COL32(255, 0, 0, 255));
draw_list->AddCircle(center, 35.0f, IM_COL32(255, 255, 255, 255), 0, 2.0f);
AddNgon / AddNgonFilled
void AddNgon(const ImVec2& center, float radius, ImU32 col,
int num_segments, float thickness = 1.0f);
void AddNgonFilled(const ImVec2& center, float radius, ImU32 col, int num_segments);
Draw a regular polygon with specified number of sides.
Number of sides (e.g., 5 for pentagon, 6 for hexagon)
AddEllipse / AddEllipseFilled
void AddEllipse(const ImVec2& center, const ImVec2& radius, ImU32 col,
float rot = 0.0f, int num_segments = 0, float thickness = 1.0f);
void AddEllipseFilled(const ImVec2& center, const ImVec2& radius, ImU32 col,
float rot = 0.0f, int num_segments = 0);
Draw an ellipse.
Text
AddText
void AddText(const ImVec2& pos, ImU32 col, const char* text_begin,
const char* text_end = NULL);
void AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32 col,
const char* text_begin, const char* text_end = NULL,
float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL);
Draw text at specified position.
End of text string (NULL for null-terminated)
Font to use (extended version)
Font size (extended version)
Curves
AddBezierCubic
void AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4,
ImU32 col, float thickness, int num_segments = 0);
Draw a cubic Bezier curve (4 control points).
AddBezierQuadratic
void AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3,
ImU32 col, float thickness, int num_segments = 0);
Draw a quadratic Bezier curve (3 control points).
See Also