API Reference: Graphics Module
Source of truth:
include/graphics/Renderer.hinclude/graphics/Camera2D.hinclude/graphics/CameraEffects.hinclude/graphics/Color.hinclude/graphics/Font.h,include/graphics/FontManager.hinclude/graphics/StaticTilemapLayerCache.hinclude/graphics/DirtyGrid.hinclude/graphics/TileAnimation.hinclude/graphics/DrawSurface.h,include/graphics/BaseDrawSurface.hinclude/graphics/TransitionEffect.hinclude/graphics/particles/*.h
Overview
This document covers the rendering system, sprites, tilemaps, colors, fonts, and particle system in PixelRoot32. The Renderer provides a unified high-level API for drawing shapes, text, and images, abstracting the underlying hardware implementation (such as DrawSurface).
Platform Optimizations (ESP32)
The engine includes several low-level optimizations for the ESP32 platform to maximize performance:
- DMA Support: Buffer transfers to the display are handled via DMA (
pushImageDMA), allowing the CPU to process the next frame concurrently. - IRAM Execution: Critical rendering functions (
drawPixel,drawSpriteInternal,resolveColor,drawTileMap) run from internal RAM (IRAM_ATTR). - Palette Caching: Tilemaps cache the resolved RGB565 LUT per tile.
- Viewport Culling: All tilemap rendering functions automatically skip tiles outside the screen boundaries.
- Dirty Region Tracking: Selective framebuffer clear via
DirtyGrid(double-buffer prev/curr with 8×8 cells), reducing memset overhead. - Direct logical framebuffer: The
TFT_eSPIdriver exposes an 8bpp sprite memory buffer, enablingRendererto write packed 2bpp/4bpp pixels directly without virtual function overhead.
Multi-layer 4bpp tilemap framebuffer snapshot (StaticTilemapLayerCache)
Avoids redrawing "static" 4bpp tilemaps every frame. It caches the static group of tiles into an internal buffer and restores it via memcpy each frame, so only dynamic elements need redrawing until the camera moves.
Dirty Regions Interaction: When both the static cache and Dirty Regions are enabled, the cache advises
beginFrame()to skip its selective or full clear if a cachememcpywill entirely overwrite the framebuffer anyway.
Key Concepts
Camera2D
Manages the viewport and scrolling of the game world. Handles coordinate transformations and target following with configurable dead zones.
CameraEffectsSystem
(Requires PIXELROOT32_ENABLE_CAMERA_EFFECTS=1)
Manages up to 4 simultaneous camera effects with round-robin insertion. Effects are updated each frame and the summed offset is retrieved via getOffset() for application to a Camera2D.
Effect Types:
| Type | Description | Use Case |
|---|---|---|
Shake | Random oscillation with amplitude | Explosions, impacts, earthquakes |
Punch | Directional impulse with linear decay | Hits, kicks, knockback |
Offset | Constant displacement for duration | Camera lerp, recoil |
API:
#include <CameraEffects.h>
using namespace pixelroot32::graphics;
// Initialize
CameraEffectsSystem effects;
// Trigger effects
effects.triggerShake(2.0f, 200); // amplitude, duration (ms)
effects.triggerPunch(3.0f, 150, Vector2(-1, 0)); // amp, dur, direction
effects.triggerOffset(4.0f, 100); // amplitude, duration
// Update (call each frame)
effects.update(deltaTime);
// Get offset (apply to Camera2D)
if (effects.hasActiveEffects()) {
math::Vector2 offset = effects.getOffset();
camera.applyWithEffect(renderer, offset);
}
// Cancel all effects
effects.cancelAll();Performance:
- Zero heap allocation (
std::array<EffectSlot, 4>) - Fast early-out via
hasActiveEffects() - Shake uses Xorshift32 random (pure integer math, no floats)
- Stub implementation when disabled (zero overhead)
Feature Gate:
; platformio.ini
build_flags =
-DPIXELROOT32_ENABLE_CAMERA_EFFECTS=1When disabled, CameraEffectsSystem becomes a no-op stub — all methods return zero/empty, no RAM or CPU cost.
Color and Palettes
The engine supports indexed colors via the Color enumeration.
- PaletteType:
PR32,NES,GB,GBC,PICO8. - Supports single palette mode or dual palette mode (separate background and sprite palettes).
Font System
Uses a native bitmap font system via 1bpp sprites (struct Font).
FONT_5X7: A built-in 5x7 pixel bitmap font (ASCII 32-126).FontManagermanages the active default font and text width calculations.
Sprite Structures
Sprite: Compact 1bpp monochrome bitmap descriptor.Sprite2bpp/Sprite4bpp: Packed multi-color sprites with a local palette (requires compile flags).SpriteLayer/MultiSprite: Layered multi-color sprites built from monochrome layers.
TileMaps
Generic descriptors for tile-based backgrounds, instantiated as TileMap (1bpp), TileMap2bpp, or TileMap4bpp.
- Tilemap rendering notes:
drawTileMapalways applies viewport culling. For static 4bpp reuse, seeStaticTilemapLayerCache.
Tile Animation System
Enables frame-based tile animations (water, lava, fire) while maintaining static tilemap data. Pacing uses high-resolution wall time so animations stay correct regardless of frame skipping.
- A
TileAnimationManagercomputes theVisualSignatureto inform the scene if a redraw is necessary.
Dirty Region System
The Dirty Region System provides selective framebuffer clearing to reduce unnecessary memset operations when most of the screen stays unchanged.
DirtyGrid(requiresPIXELROOT32_ENABLE_DIRTY_REGIONS=1): Double-buffer design withprevandcurrbit-packed grids of 8×8 pixel cells. Each cell tracks whether it was drawn to in the current frame.LayerType(ininclude/graphics/Renderer.h): Classifies tilemaps to enable selective tracking:LayerType::Static: Background layers that rarely change. The system tracks dirty cells, but the layer itself doesn't mark cells as dirty.LayerType::Dynamic: Sprites, particles, and UI that move every frame. These mark their occupied cells as dirty.
forceFullRedraw(): Call this when a full framebuffer clear is required (scene transitions, pause menus, camera jumps). Resets the dirty grid state and synchronizes the internal bit buffer.TilemapSpriteDirtyMode: Controls per-sprite dirty marking behavior. UseSuppressPerSpriteBoundsMarkfor static or selectively-animated tilemaps to avoid marking cells as dirty unnecessarily.Debug overlay (
setDebugDirtyCellOverlay): Visualizes dirty cells on screen for debugging. RequiresPIXELROOT32_DEBUG_MODE=1.Compile flag:
PIXELROOT32_ENABLE_DIRTY_REGIONS(default: disabled). RAM cost:2 × ceil(cols × rows / 8)bytes — 60 bytes for 120×120, 226 bytes for 240×240.
Tip: Use
LayerType::Staticfor backgrounds that don't change—avoids unnecessary dirty cell marking.
Tile Attribute System
Provides runtime access to custom metadata attached to tiles. Attributes are stored in Flash memory on the ESP32.
IMPORTANT
Since attributes are stored in Flash memory on ESP32, you must use PIXELROOT32_STRCMP_P or PIXELROOT32_MEMCPY_P to compare or copy the returned values.
Particle System
(Requires PIXELROOT32_ENABLE_PARTICLES=1) Provides lightweight visual effects using a fixed-size pool of Particle objects. Managed by a ParticleEmitter entity.
- ParticlePresets: Predefined configs (
Fire,Explosion,Sparks,Smoke,Dust).
SpriteAnimation
Lightweight, step-based animation controller for advancing through an array of SpriteAnimationFrame.
DrawSurface / BaseDrawSurface
Abstract interfaces for platform-specific drawing operations (e.g., SDL2_Drawer, TFT_eSPI_Drawer).
TransitionEffect
(Requires PIXELROOT32_ENABLE_SCENE_TRANSITIONS=1)
Provides scene transition effects (Fade and Iris) for smooth visual transitions between scenes. Uses direct 8bpp buffer access for zero-allocation, ESP32-friendly implementation.
Transition Types:
| Type | Method | Description |
|---|---|---|
Fade | Palette manipulation | Smooth global dimming via 256-byte LUT |
Iris | Buffer circle | Circular wipe using squared-distance test |
API:
#include <TransitionEffect.h>
using namespace pixelroot32::graphics;
// Create effect
TransitionEffect effect;
// Start transition
effect.begin(TransitionType::Fade, 500, TransitionDirection::Out);
// Update (call each frame)
effect.update(deltaTime);
// Apply to buffer
if (effect.isActive()) {
uint8_t* buffer = surface->getSpriteBuffer();
effect.apply(buffer, logicalWidth, logicalHeight);
}
// Check completion
if (effect.isComplete()) {
// Transition finished
}
// Iris customization
effect.setIrisCenter(64, 64); // Set circle centerPerformance:
- Fade: ~2-4% frame budget (LUT lookup per pixel)
- Iris: ~2.8% frame budget (squared-distance test, no sqrt)
- Zero heap allocation (256-byte LUT on stack)
- Direct buffer access via
getSpriteBuffer()
Feature Gate:
; platformio.ini
build_flags =
-DPIXELROOT32_ENABLE_SCENE_TRANSITIONS=1When disabled, TransitionEffect becomes a no-op stub — all methods are safe to call but do nothing.
See Scene Management Guide for usage examples.
Related Types
Renderer→include/graphics/Renderer.hCamera2D→include/graphics/Camera2D.hCameraEffectsSystem→include/graphics/CameraEffects.hTransitionEffect→include/graphics/TransitionEffect.hColor,PaletteType→include/graphics/Color.hFont,FontManager→include/graphics/FontManager.hSprite,TileMap→include/graphics/Renderer.hDirtyGrid→include/graphics/DirtyGrid.hLayerType→include/graphics/Renderer.hParticleEmitter,ParticleConfig→include/graphics/particles/ParticleEmitter.hTileAnimationManager→include/graphics/TileAnimation.h
Related Documentation
- API Reference - Main index
- Core Module - Engine, Entity, Scene
- Physics Module - Collision system
- UI Module - User interface system
