Shapes
2D drawing primitives — rectangles, lines, circles, triangles, polygons, and
individual pixels — are all methods on the
RaylibDraw
trait. The trait is implemented by RaylibDrawHandle, so all calls live inside the
begin_drawing scope. No extra state or resource loading is required; shapes are
drawn immediately with a color and optional parameters for thickness, rounding, or
gradients.
API surface
draw_rectangle— filled rectangle by position + size.draw_rectangle_v— filled rectangle byVector2position + size.draw_rectangle_rec— filled rectangle from aRectanglevalue.draw_circle— filled circle by center + radius.draw_circle_v— filled circle byVector2center + radius.draw_line— 1-pixel line between two integer points.draw_line_ex— thick line between twoVector2points with athicknessparameter.draw_triangle— filled triangle from threeVector2vertices (counter-clockwise winding).draw_poly— filled regular polygon (n sides).draw_pixel— single pixel by integer coordinates.
Example
The example opens a window and draws a rectangle and a circle every frame. A software-renderer version of this is available as part of the WS9 showcase; the live example here requires a display.
extern crate raylib;
use raylib::prelude::*;
fn main() {
let (mut rl, thread) = raylib::init()
.size(640, 480)
.title("Shapes demo")
.vsync()
.build();
while !rl.window_should_close() {
let mut d = rl.begin_drawing(&thread);
d.clear_background(Color::RAYWHITE);
// Filled rectangle at (50, 50), 200×100, blue.
d.draw_rectangle(50, 50, 200, 100, Color::BLUE);
// Filled circle at (400, 200), radius 80, red.
d.draw_circle(400, 200, 80.0, Color::RED);
// 1-pixel line from (0, 0) to (640, 480), dark gray.
d.draw_line(0, 0, 640, 480, Color::DARKGRAY);
}
}
Gotchas
Shapes are stable across raylib 5.x and 6.0; there are no breaking changes to the 2D primitive set. The only points worth noting:
- Counter-clockwise winding for
draw_triangle. raylib expects vertices in counter-clockwise order; clockwise-wound triangles are culled. - Integer vs. vector variants. Most primitives have both an integer overload
(
draw_circle(cx: i32, cy: i32, …)) and a_voverload (draw_circle_v(center: Vector2, …)). Prefer_vwhen your coordinates are alreadyVector2.
See also
- Window and drawing — the
begin_drawingscope that all shape calls live inside. - Textures and images — blitting pixel buffers and textures in the same draw scope.
- Software renderer — running headless shape tests.
Showcase examples
Showcase examples that exercise this module: