Renderer¶
High-level graphics rendering system for drawing shapes, text, sprites, and tilemaps.
Description¶
The Renderer class provides a unified API for drawing shapes, text, and images. It abstracts the underlying hardware implementation (DrawSurface) and manages display configuration, including rotation and resolution scaling.
All drawing operations are performed in logical screen space. If the logical resolution differs from the physical resolution, the renderer will automatically scale the output to fit the display using a high-performance nearest-neighbor algorithm.
The renderer uses integer-only math for optimal performance on ESP32 and supports multiple sprite formats (1bpp, 2bpp, 4bpp) and multi-layer sprites.
Namespace¶
Inheritance¶
- Base class: None (standalone class)
- Used by:
Engine(manages renderer instance)
Constructors¶
Renderer(const DisplayConfig& config)¶
Constructs the Renderer with a specific display configuration.
Parameters:
config(constDisplayConfig&): The display configuration settings (width, height, rotation, etc.)
Example:
#include "graphics/Renderer.h"
#include "graphics/DisplayConfig.h"
// 128x128 game logic scaled to 240x240 display
pixelroot32::graphics::DisplayConfig config(
pixelroot32::graphics::DisplayType::ST7789,
0, // rotation
240, 240, // physical resolution
128, 128 // logical resolution (rendering space)
);
pixelroot32::graphics::Renderer renderer(config);
renderer.init();
Public Methods¶
void init()¶
Initializes the renderer and the underlying draw surface.
Returns:
void
Notes:
- Must be called after construction and before any drawing operations
- Initializes the platform-specific
DrawSurfaceimplementation - Safe to call multiple times (idempotent)
Example:
void beginFrame()¶
Prepares the buffer for a new frame (clears screen).
Returns:
void
Notes:
- Should be called once at the start of each frame
- Clears the display buffer
- Typically called automatically by
Engine, but can be called manually
Example:
void draw(Renderer& renderer) override {
renderer.beginFrame();
// Draw everything...
renderer.endFrame();
}
void endFrame()¶
Finalizes the frame and sends the buffer to the display.
Returns:
void
Notes:
- Should be called once at the end of each frame
- Sends the completed frame buffer to the display
- Typically called automatically by
Engine, but can be called manually
void setOffsetBypass(bool bypass)¶
Enables or disables camera offset bypass.
Parameters:
bypass(bool):trueto ignore global offsets,falseto apply them.
Notes:
- When enabled, all subsequent draw calls will ignore
xOffsetandyOffset. - Useful for drawing fixed UI elements that should not move with the camera.
bool isOffsetBypassEnabled() const¶
Checks if the offset bypass is currently active.
Returns:
bool:trueif bypass is enabled.
DrawSurface& getDrawSurface()¶
Gets the underlying DrawSurface implementation.
Returns:
DrawSurface&: Reference to the DrawSurface
Notes:
- Advanced usage: typically not needed unless implementing custom drawing
- Provides low-level access to the display driver
void drawText(std::string_view text, int16_t x, int16_t y, Color color, uint8_t size)¶
Draws a string of text using the default font and scaling.
Parameters:
text(std::string_view): The text to drawx(int16_t): X coordinate (top-left corner of text)y(int16_t): Y coordinate (top-left corner of text)color(Color): Text colorsize(uint8_t): Text size multiplier (1 = 5x7 pixels, 2 = 10x14 pixels, etc.)
Performance Notes:
- Efficient for small amounts of text
- Uses integer-only scaling (no floats)
Example:
renderer.drawText("Hello World", 10, 10, Color::White, 1);
renderer.drawText("Score: 100", 10, 30, Color::Yellow, 2);
void drawText(std::string_view text, int16_t x, int16_t y, Color color, uint8_t size, const Font* font)¶
Draws a string of text using a specific font and scaling.
Parameters:
text(std::string_view): The text to drawx(int16_t): X coordinatey(int16_t): Y coordinatecolor(Color): Text colorsize(uint8_t): Text size multiplierfont(const Font*): Pointer to the font to use. Ifnullptr, uses the default font
Example:
const Font* customFont = &FONT_5X7;
renderer.drawText("Custom Font", 10, 10, Color::White, 1, customFont);
void drawTextCentered(std::string_view text, int16_t y, Color color, uint8_t size)¶
Draws text centered horizontally at a given Y coordinate using the default font.
Parameters:
text(std::string_view): The text to drawy(int16_t): Y coordinatecolor(Color): Text colorsize(uint8_t): Text size
Example:
void drawTextCentered(std::string_view text, int16_t y, Color color, uint8_t size, const Font* font)¶
Draws text centered horizontally at a given Y coordinate using a specific font.
Parameters:
text(std::string_view): The text to drawy(int16_t): Y coordinatecolor(Color): Text colorsize(uint8_t): Text sizefont(const Font*): Pointer to the font to use. Ifnullptr, uses the default font
void drawFilledCircle(int x, int y, int radius, Color color)¶
Draws a filled circle.
Parameters:
x(int): Center X coordinatey(int): Center Y coordinateradius(int): Radius of the circle in pixelscolor(Color): Fill color
Example:
void drawCircle(int x, int y, int radius, Color color)¶
Draws a circle outline.
Parameters:
x(int): Center X coordinatey(int): Center Y coordinateradius(int): Radius of the circle in pixelscolor(Color): Outline color
Example:
void drawRectangle(int x, int y, int width, int height, Color color)¶
Draws a rectangle outline.
Parameters:
x(int): Top-left X coordinatey(int): Top-left Y coordinatewidth(int): Width of the rectangle in pixelsheight(int): Height of the rectangle in pixelscolor(Color): Outline color
Example:
void drawFilledRectangle(int x, int y, int width, int height, Color color)¶
Draws a filled rectangle.
Parameters:
x(int): Top-left X coordinatey(int): Top-left Y coordinatewidth(int): Width of the rectangle in pixelsheight(int): Height of the rectangle in pixelscolor(Color): Fill color
Example:
void drawLine(int x1, int y1, int x2, int y2, Color color)¶
Draws a line between two points.
Parameters:
x1(int): Start X coordinatey1(int): Start Y coordinatex2(int): End X coordinatey2(int): End Y coordinatecolor(Color): Line color
Example:
void drawPixel(int x, int y, Color color)¶
Draws a single pixel.
Parameters:
x(int): X coordinatey(int): Y coordinatecolor(Color): Pixel color
Performance Notes:
- Very fast, but avoid calling thousands of times per frame
- Use for special effects or debugging
Example:
void drawSprite(const Sprite& sprite, int x, int y, Color color, bool flipX = false)¶
Draws a 1bpp monochrome sprite using the Sprite descriptor.
Parameters:
sprite(constSprite&): Sprite descriptor (data, width, height)x(int): Top-left X coordinate in logical screen spacey(int): Top-left Y coordinate in logical screen spacecolor(Color): Color used for "on" pixelsflipX(bool, optional): Iftrue, sprite is mirrored horizontally. Default:false
Performance Notes:
- Very efficient for 1bpp sprites (integer-only operations)
- Sprite data should be stored in flash (const/constexpr) for best performance
Example:
renderer.drawSprite(playerSprite, 100, 100, Color::White);
renderer.drawSprite(playerSprite, 120, 100, Color::White, true); // Flipped
void drawSprite(const Sprite& sprite, int x, int y, float scaleX, float scaleY, Color color, bool flipX = false)¶
Draws a scaled 1bpp monochrome sprite using nearest-neighbor scaling.
Parameters:
sprite(constSprite&): Sprite descriptorx(int): Top-left X coordinatey(int): Top-left Y coordinatescaleX(float): Horizontal scaling factor (e.g., 2.0 for double width)scaleY(float): Vertical scaling factorcolor(Color): Color used for "on" pixelsflipX(bool, optional): Iftrue, sprite is mirrored horizontally before scaling. Default:false
Performance Notes:
- Slower than non-scaled version due to scaling calculations
- The destination size is calculated as
ceil(width * scaleX) x ceil(height * scaleY)
Example:
void drawSprite(const Sprite2bpp& sprite, int x, int y, bool flipX = false)¶
Draws a 2bpp sprite. Available when PIXELROOT32_ENABLE_2BPP_SPRITES is defined.
Parameters:
sprite(constSprite2bpp&): 2bpp sprite descriptorx(int): X coordinatey(int): Y coordinateflipX(bool, optional): Horizontal flip. Default:false
void drawSprite(const Sprite4bpp& sprite, int x, int y, bool flipX = false)¶
Draws a 4bpp sprite. Available when PIXELROOT32_ENABLE_4BPP_SPRITES is defined.
Parameters:
sprite(constSprite4bpp&): 4bpp sprite descriptorx(int): X coordinatey(int): Y coordinateflipX(bool, optional): Horizontal flip. Default:false
void drawMultiSprite(const MultiSprite& sprite, int x, int y)¶
Draws a multi-layer sprite composed of several 1bpp layers.
Parameters:
sprite(constMultiSprite&): Multi-layer sprite descriptorx(int): Top-left X coordinate in logical screen spacey(int): Top-left Y coordinate in logical screen space
Performance Notes:
- Each layer is rendered separately, so more layers = more draw calls
- Still efficient as each layer uses 1bpp format
- Use for multi-color sprites without higher bit-depths
Example:
static const SpriteLayer layers[] = {
{ outlineData, Color::Black },
{ fillData, Color::Red },
{ highlightData, Color::Yellow }
};
static const MultiSprite playerMultiSprite = {
8, // width
8, // height
layers, // layers array
3 // layer count
};
renderer.drawMultiSprite(playerMultiSprite, 100, 100);
void drawMultiSprite(const MultiSprite& sprite, int x, int y, float scaleX, float scaleY)¶
Draws a scaled multi-layer sprite.
Parameters:
sprite(constMultiSprite&): Multi-layer sprite descriptorx(int): Top-left X coordinatey(int): Top-left Y coordinatescaleX(float): Horizontal scaling factorscaleY(float): Vertical scaling factor
void drawTileMap(const TileMap& map, int originX, int originY, Color color)¶
Draws a 1bpp tilemap.
Parameters:
map(constTileMap&): Tilemap descriptor (indices, 1bpp tiles, dimensions)originX(int): X coordinate of the top-left corneroriginY(int): Y coordinate of the top-left cornercolor(Color): Color used for all tiles in the map
void drawTileMap(const TileMap2bpp& map, int originX, int originY)¶
Draws a 2bpp tilemap. Available when PIXELROOT32_ENABLE_2BPP_SPRITES is defined.
Parameters:
map(constTileMap2bpp&): Tilemap descriptor (indices, 2bpp tiles, dimensions)originX(int): X coordinateoriginY(int): Y coordinate
void drawTileMap(const TileMap4bpp& map, int originX, int originY)¶
Draws a 4bpp tilemap. Available when PIXELROOT32_ENABLE_4BPP_SPRITES is defined.
Parameters:
map(constTileMap4bpp&): Tilemap descriptor (indices, 4bpp tiles, dimensions)originX(int): X coordinateoriginY(int): Y coordinate
Performance Notes:
- Very efficient for rendering large backgrounds
- Only visible tiles are drawn (viewport culling)
- Use tilemaps instead of individual sprites for backgrounds
Example:
static const uint8_t levelIndices[] = {
0, 1, 2, 3,
4, 5, 6, 7,
// ... more rows
};
static const TileMap levelMap = {
levelIndices,
16, // width in tiles
16, // height in tiles
tileSprites, // tile sprite array
8, // tile width
8, // tile height
16 // tile count
};
renderer.drawTileMap(levelMap, 0, 0, Color::White);
int getLogicalWidth() const¶
Gets the logical rendering width.
Returns:
int: The width of the logical screen space.
int getLogicalHeight() const¶
Gets the logical rendering height.
Returns:
int: The height of the logical screen space.
Note: These methods replace the removed
getWidth()andgetHeight().
void setDisplayOffset(int x, int y)¶
Sets a global offset for all drawing operations. Useful for camera/parallax effects.
Parameters:
x(int): X offset in pixelsy(int): Y offset in pixels
Notes:
- All subsequent drawing operations are offset by this amount
- Useful for camera scrolling and parallax effects
- Reset to (0, 0) to disable offset
Example:
// Camera scrolling
camera.setPosition(playerX - 64, playerY - 64);
renderer.setDisplayOffset(-camera.getX(), -camera.getY());
renderer.drawTileMap(background, 0, 0, Color::White);
void setDisplaySize(int w, int h)¶
Sets the logical display size.
Parameters:
w(int): Width in pixelsh(int): Height in pixels
Notes:
- Typically set via
DisplayConfigduring construction - Use this to change display size at runtime if needed
int getXOffset() const¶
Gets the current X display offset.
Returns:
int: X offset in pixels
int getYOffset() const¶
Gets the current Y display offset.
Returns:
int: Y offset in pixels
void setContrast(uint8_t level)¶
Sets the display contrast (brightness).
Parameters:
level(uint8_t): Contrast level (0-255)
Notes:
- Platform-specific: may not be supported on all displays
- Higher values = brighter display
void setFont(const uint8_t* font)¶
Sets the font for text rendering.
Parameters:
font(const uint8_t*): Pointer to the font data
Notes:
- Sets the default font for
drawText()calls without font parameter - Use font constants like
FONT_5X7fromFont.h
Usage Example¶
#include "graphics/Renderer.h"
#include "graphics/DisplayConfig.h"
void draw(Renderer& renderer) override {
renderer.beginFrame();
// Draw background
renderer.drawFilledRectangle(0, 0, 128, 128, Color::Black);
// Draw sprites
renderer.drawSprite(playerSprite, playerX, playerY, Color::White);
renderer.drawSprite(enemySprite, enemyX, enemyY, Color::Red);
// Draw UI
renderer.drawText("Score: 100", 10, 10, Color::White, 1);
renderer.drawTextCentered("Game Over", 64, Color::Yellow, 2);
renderer.endFrame();
}
Performance Considerations¶
- Integer-only math: All operations use integer arithmetic for ESP32 efficiency
- Sprite storage: Store sprite data in flash (const/constexpr) for best performance
- Batch operations: Group similar draw calls together
- Tilemaps: Dibuja un mapa de tiles completo. Implementa viewport culling automático y caché de paleta para máximo rendimiento.
- Sprites 2bpp/4bpp: Optimizado para ESP32 (IRAM + acceso de 16 bits).
ESP32 Considerations¶
- Memory: Sprite data should be in flash, not RAM
- Frame rate: Limit draw calls per frame for consistent FPS
- Display offset: Use for scrolling instead of redrawing everything
See Also¶
- Sprite - Sprite structure
- MultiSprite - Multi-layer sprites
- TileMap - Tilemap structure
- Color - Color constants
- DisplayConfig - Display configuration
- Camera2D - Camera for scrolling
- Manual - Basic Rendering
- Manual - Sprites and Animation
- API Overview