Renderer

micro::renderer is the 2D hardware-accelerated renderer. It wraps SDL's renderer with vsync enabled and nearest-neighbour (pixel art) texture filtering.

Draw calls using the same texture are batched automatically and submitted to the GPU in a single call. The batch is flushed when the texture changes or present() is called.

Construction

// At window resolution:
micro::renderer rend{win};

// With a fixed logical size (letterboxed by default):
micro::renderer rend{win, 320, 240};

// Stretched to fill without letterboxing:
micro::renderer rend{win, 320, 240, true};

When a logical size is active, all draw calls use logical coordinates. Convert window-space mouse positions with to_logical() before comparing them to game objects.

Frame lifecycle

void clear(color c);    // fill the target with a solid color (flushes batch first)
void present();         // flush draw calls and swap the back buffer

Typical frame:

win.run([&](float dt) {
    rend.clear(micro::color::black);
    // ... draw calls ...
    rend.present();
});

Textures

void draw(const texture& tex, pointf pos, const draw_options& opts = {});
void draw(const texture& tex, rect src, pointf pos, const draw_options& opts = {});

The first overload draws the full texture at pos. The second draws the sub-region src (a pixel rectangle within the texture), useful for sprite sheets.

See Draw options for tint, scale, flip, and rotation.

// Full texture:
rend.draw(hero_tex, {100.f, 80.f});

// Sprite sheet frame at (0,0,16,16), flipped horizontally:
rend.draw(sheet_tex, {0, 0, 16, 16}, {100.f, 80.f}, draw_options{}.flip(flip::horizontal));

Text

There are two ways to render text:

Pre-created text objects

void draw(const text& txt, pointf pos, const text_options& opts = {});

Renders a Text object with the top-left at pos. This is efficient for static or frequently rendered text (UI elements, dialog boxes) since the text layout is calculated once during construction.

// Create once, render every frame:
micro::text health_label{fnt, "Health:"};
rend.draw(health_label, {10.f, 10.f});

// Multiline text with centered lines:
micro::text dialog{fnt, "Welcome, traveler.\nWhat brings you here?"};
rend.draw(dialog, {20.f, 100.f}, text_options{}.align(align::center));

// Scaled and tinted:
rend.draw(title, {160.f, 20.f}, text_options{}.scale(2.f).tint(color::yellow));

Temporary text

void draw(const font& fnt, std::string_view text, pointf pos,
          const text_options& opts = {});

Convenience method that constructs a temporary text internally. Good for one-off or dynamic text (damage numbers, debug output) where the construction overhead is acceptable.

// Temporary text:
rend.draw(fnt, "Score: 42", {8.f, 8.f});

// With options:
rend.draw(fnt, "Game Over", {80.f, 100.f},
          text_options{}.tint(color::yellow).scale(2.f));

Unknown characters are silently skipped. The opts.scale() scales both rendered glyphs and advance widths. See Text options for details.

See Text for the text class, Font for font loading and custom fonts, and Text options for rendering options.

Primitives

void draw_pixel(pointf pos, color c);
void draw_line (pointf from, pointf to, color c);
void fill_rect (rectf r, color c);
void draw_rect (rectf r, color c);

draw_pixel occupies [pos.x, pos.x+1) × [pos.y, pos.y+1).

Axis-aligned lines are a single fill_rect. Diagonal lines use Bresenham's algorithm.

draw_rect draws the four edges; fill_rect fills the whole region.

Coordinate conversion

[[nodiscard]] pointf to_logical(pointf window_pos) const noexcept;

Converts a window-space position to logical coordinates. Passthrough when no logical size is set.

auto lp = rend.to_logical(mouse.position());

Driver name

[[nodiscard]] std::string name() const;  // e.g. "direct3d11", "metal", "opengl"