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"