IRenderer#
Base class for renderer.
| Header: | #include <AUI/Render/IRenderer.h> |
| CMake: | aui_link(my_target PUBLIC aui::views) |
Detailed Description#
The rendering engine provides graphics rendering capabilities for the AUI Framework's user interface system. It offers both hardware-accelerated (OpenGL) and software-based rendering backends. The engine handles drawing primitives, text rendering, visual effects, and maintains consistent rendering behavior across different platforms and hardware capabilities.
The renderer is shared across windows and manages its own resources such as textures, but each window has its own rendering context.
Core Renderer Interface#
| Category | Key Methods | Purpose |
|---|---|---|
| Shape Drawing | rectangle(), roundedRectangle(), rectangleBorder() |
Basic geometric shapes |
| Line Drawing | line(), lines(), points() |
Vector graphics primitives |
| Text Rendering | string(), prerenderString(), newMultiStringCanvas() |
Text output and caching |
| Visual Effects | boxShadow(), boxShadowInner(), squareSector() |
Advanced visual effects |
| State Management | setColor(), setTransform(), setBlending() |
Rendering context control |
| Masking | pushMaskBefore(), pushMaskAfter(), popMaskBefore(), popMaskAfter() |
Stencil-based clipping |
The renderer maintains internal state including:
- Current color multiplier (mColor)
- Transformation matrix (mTransform)
- Target window (mWindow)
- Stencil depth for masking (mStencilDepth)
- Texture pool for resource management (mTexturePool)
HiDPI (High‑DPI) support#
The framework uses logical units dp for layout and drawing. All logical values are multiplied by the window pixel ratio before they reach the renderer. The renderer works with physical pixels only (px).
This ensures that the UI appears consistent across displays with varying pixel densities.
Examples#
examples/ui/embedded_sdl/src/main.cpp
SDL3 - This code demonstrates how to integrate the AUI Framework with SDL3 to create a window with OpenGL rendering.
Public Types#
IPrerenderedString#
class IRenderer::IPrerenderedString
Empty structure.
IMultiStringCanvas#
class IRenderer::IMultiStringCanvas
Empty structure.
Public Methods#
backdrops#
void IRenderer::backdrops(glm::ivec2 position, glm::ivec2 size, std::span<ass::Backdrop::Any> backdrops)
Draws rectangular backdrop effects.
- Arguments
positionrectangle position (px)sizerectangle size (px)backdropsarray of backdrop effects. Impl might apply optimizations on using several effects at once.
Implementation might draw stub (i.e., gray rectangle) instead of drawing complex backdrop effects.
boxShadow#
virtual void IRenderer::boxShadow(glm::vec2 position, glm::vec2 size, float blurRadius, const AColor& color)
Draws a rectangle-shaped shadow.
- Arguments
positionpositionsizerectangle sizeblurRadiusblur radiuscolorshadow color
boxShadowInner#
virtual void IRenderer::boxShadowInner(glm::vec2 position, glm::vec2 size, float blurRadius, float spreadRadius, float borderRadius, const AColor& color, glm::vec2 offset)
Draws inner (inset) rectangle-shaped shadow.
- Arguments
positionpositionsizerectangle sizeblurRadiusblur radiusspreadRadiusspread (offset) radiusborderRadiusborder radius of the rectangle.colorshadow coloroffsetshadow offset. Unlike outer shadow (ctx.render.boxShadow), the offset is passed to the shader instead of a simple rectangle position offset.
getNewTexture#
Creates new texture (image representation optimized for GPU rendering).
Examples:
examples/app/game_of_life/src/main.cpp
Game of Life - Game of Life implementation that uses advanced large dynamic data rendering techniques such as ITexture, AImage to be GPU friendly. The computation is performed in AThreadPool.
line#
void IRenderer::line(const ABrush& brush, glm::vec2 p1, glm::vec2 p2, const ABorderStyle& style = ABorderStyle::Solid { }, AMetric width = 1 _dp)
- Performance note
- if you want to drawElements multiple lines, consider using
ARender::linesfunction instead.
lines#
virtual void IRenderer::lines(const ABrush& brush, AArrayView<glm::vec2> points, const ABorderStyle& style, AMetric width)
Draws polyline (non-loop line strip).
- Arguments
brushbrushpointspolyline pointsstylestylewidthline width
Examples:
examples/ui/views/src/DemoGraphView.cpp
Views Example - All-in-one views building example.
void DemoGraphView::render(ARenderContext ctx) {
AView::render(ctx);
ctx.render.lines(ASolidBrush{0xff0000_rgb }, mPoints, ABorderStyle::Dashed{}, 4_dp);
}
examples/app/game_of_life/src/main.cpp
Game of Life - Game of Life implementation that uses advanced large dynamic data rendering techniques such as ITexture, AImage to be GPU friendly. The computation is performed in AThreadPool.
}
for (int i = 1; i < mCells->size().y; ++i) {
points << std::make_pair(glm::vec2(0.f, i * SCALE), glm::vec2(getSize().x, i * SCALE));
}
ctx.render.lines(ASolidBrush { AColor::GRAY }, points);
};
drawGrid();
}
void onPointerPressed(const APointerPressedEvent& event) override {
void IRenderer::lines(const ABrush& brush, AArrayView<glm::vec2> points, const ABorderStyle& style = ABorderStyle::Solid { })
Draws polyline (non-loop line strip).
- Arguments
brushbrushpointspolyline pointsstylestyle
Examples:
examples/ui/views/src/DemoGraphView.cpp
Views Example - All-in-one views building example.
void DemoGraphView::render(ARenderContext ctx) {
AView::render(ctx);
ctx.render.lines(ASolidBrush{0xff0000_rgb }, mPoints, ABorderStyle::Dashed{}, 4_dp);
}
examples/app/game_of_life/src/main.cpp
Game of Life - Game of Life implementation that uses advanced large dynamic data rendering techniques such as ITexture, AImage to be GPU friendly. The computation is performed in AThreadPool.
}
for (int i = 1; i < mCells->size().y; ++i) {
points << std::make_pair(glm::vec2(0.f, i * SCALE), glm::vec2(getSize().x, i * SCALE));
}
ctx.render.lines(ASolidBrush { AColor::GRAY }, points);
};
drawGrid();
}
void onPointerPressed(const APointerPressedEvent& event) override {
virtual void IRenderer::lines(const ABrush& brush, AArrayView<std::pair<glm::vec2, glm::vec2> > points, const ABorderStyle& style, AMetric width)
Draws multiple individual lines in a batch.
- Arguments
brushbrushpointsline pointsstylestylewidthline width
Examples:
examples/ui/views/src/DemoGraphView.cpp
Views Example - All-in-one views building example.
void DemoGraphView::render(ARenderContext ctx) {
AView::render(ctx);
ctx.render.lines(ASolidBrush{0xff0000_rgb }, mPoints, ABorderStyle::Dashed{}, 4_dp);
}
examples/app/game_of_life/src/main.cpp
Game of Life - Game of Life implementation that uses advanced large dynamic data rendering techniques such as ITexture, AImage to be GPU friendly. The computation is performed in AThreadPool.
}
for (int i = 1; i < mCells->size().y; ++i) {
points << std::make_pair(glm::vec2(0.f, i * SCALE), glm::vec2(getSize().x, i * SCALE));
}
ctx.render.lines(ASolidBrush { AColor::GRAY }, points);
};
drawGrid();
}
void onPointerPressed(const APointerPressedEvent& event) override {
void IRenderer::lines(const ABrush& brush, AArrayView<std::pair<glm::vec2, glm::vec2> > points, const ABorderStyle& style = ABorderStyle::Solid { })
Draws multiple individual lines in a batch.
- Arguments
brushbrushpointsline pointsstylestyle
Examples:
examples/ui/views/src/DemoGraphView.cpp
Views Example - All-in-one views building example.
void DemoGraphView::render(ARenderContext ctx) {
AView::render(ctx);
ctx.render.lines(ASolidBrush{0xff0000_rgb }, mPoints, ABorderStyle::Dashed{}, 4_dp);
}
examples/app/game_of_life/src/main.cpp
Game of Life - Game of Life implementation that uses advanced large dynamic data rendering techniques such as ITexture, AImage to be GPU friendly. The computation is performed in AThreadPool.
}
for (int i = 1; i < mCells->size().y; ++i) {
points << std::make_pair(glm::vec2(0.f, i * SCALE), glm::vec2(getSize().x, i * SCALE));
}
ctx.render.lines(ASolidBrush { AColor::GRAY }, points);
};
drawGrid();
}
void onPointerPressed(const APointerPressedEvent& event) override {
newMultiStringCanvas#
virtual _<IMultiStringCanvas> IRenderer::newMultiStringCanvas(const AFontStyle& style)
Creates new canvas for batching multiple prerender string calls.
- Returns
- a new instance of
IMultiStringCanvas
newRenderViewToTexture#
virtual _unique<IRenderViewToTexture> IRenderer::newRenderViewToTexture()
Returns a new instance of IRenderViewToTexture interface associated with this renderer.
- Returns
- A new instance. Can return null if unsupported.
points#
virtual void IRenderer::points(const ABrush& brush, AArrayView<glm::vec2> points, AMetric size)
Draws points list.
- Arguments
brushbrushpointspointssizepoint size
popMaskAfter#
Switches drawing to the color buffer back from the stencil. Decreases stencil depth.
Stencil buffer should not be changed after calling this function.
Should be called after the popMaskBefore function.
popMaskBefore#
Switches drawing to the stencil buffer instead of color buffer.
Stencil pixel is decreased by each affected pixel.
Should be called before the popMaskAfter function.
prerenderString#
virtual _<IPrerenderedString> IRenderer::prerenderString(glm::vec2 position, const AString& text, const AFontStyle& fs)
Analyzes string and creates an instance of IRenderer::IPrerenderedString which helps
IRenderer to efficiently render the string.
- Arguments
positionstring baselinetextstring to prerenderfsfont style- Returns
- an instance of IPrerenderedString
pushMaskAfter#
Switches drawing to the color buffer back from the stencil. Increases stencil depth.
Stencil buffer should not be changed after calling this function.
Should be called after the pushMaskBefore function.
pushMaskBefore#
witches drawing to the stencil buffer instead of color buffer.
Stencil pixel is increased by each affected pixel.
Should be called before the pushMaskAfter function.
rectangle#
Draws simple rectangle.
- Arguments
brushbrush to usepositionrectangle position (px)sizerectangle size (px)
Examples:
examples/app/fractal/src/FractalView.cpp
Fractal Example - Fractal viewer application demonstrating usage of custom shaders.
AView::render(context);
mShader.use();
mTexture->bind();
context.render.rectangle(ACustomShaderBrush {}, { 0, 0 }, getSize());
}
void FractalView::setSize(glm::ivec2 size) {
AView::setSize(size);
mShader.use();
examples/app/game_of_life/src/main.cpp
Game of Life - Game of Life implementation that uses advanced large dynamic data rendering techniques such as ITexture, AImage to be GPU friendly. The computation is performed in AThreadPool.
void render(ARenderContext ctx) override {
AView::render(ctx);
if (mTexture) {
ctx.render.rectangle(ATexturedBrush { mTexture }, { 0, 0 }, float(SCALE) * glm::vec2(mCells->size()));
}
auto drawGrid = [&] {
ASmallVector<std::pair<glm::vec2, glm::vec2>, 128 * 2> points;
for (int i = 1; i < mCells->size().x; ++i) {
points << std::make_pair(glm::vec2(i * SCALE, 0.f), glm::vec2(i * SCALE, getSize().y));
rectangleBorder#
virtual void IRenderer::rectangleBorder(const ABrush& brush, glm::vec2 position, glm::vec2 size, float lineWidth = 1 . f)
Draws rectangle's border.
- Arguments
brushbrush to usepositionrectangle position (px)sizerectangle size (px)lineWidthborder line width (px)
rotate#
void IRenderer::rotate(const glm::vec3& axis, AAngleRadians angle)
wrapper for setTransform applying matrix rotation along the specified axis.
- Arguments
axisaxisangleangle to rotate
void IRenderer::rotate(AAngleRadians angle)
wrapper for setTransform applying matrix rotation along z axis.
- Arguments
angleangle to rotate
roundedRectangle#
virtual void IRenderer::roundedRectangle(const ABrush& brush, glm::vec2 position, glm::vec2 size, float radius)
Draws rounded rect (with antialiasing, if msaa enabled).
- Arguments
brushbrush to usepositionrectangle position (px)sizerectangle size (px)radiuscorner radius (px)
Examples:
examples/7guis/circle_drawer/src/main.cpp
7GUIs Circle Drawer - Undo, redo, dialog control.
AView::render(ctx);
for (const auto& circle : *mState->circles) {
if (&circle == mHoveredCircle) {
ctx.render.roundedRectangle(
ASolidBrush { AColor::GRAY }, circle.position - *circle.radius, glm::vec2(circle.radius * 2.f),
circle.radius);
}
ctx.render.roundedRectangleBorder(
ASolidBrush { AColor::BLACK }, circle.position - *circle.radius, glm::vec2(circle.radius * 2.f),
roundedRectangleBorder#
virtual void IRenderer::roundedRectangleBorder(const ABrush& brush, glm::vec2 position, glm::vec2 size, float radius, int borderWidth)
Draws rounded rectangle's border.
- Arguments
brushbrush to usepositionrectangle position (px)sizerectangle size (px)radiuscorner radius (px)borderWidthborder line width (px)
Examples:
examples/7guis/circle_drawer/src/main.cpp
7GUIs Circle Drawer - Undo, redo, dialog control.
ctx.render.roundedRectangle(
ASolidBrush { AColor::GRAY }, circle.position - *circle.radius, glm::vec2(circle.radius * 2.f),
circle.radius);
}
ctx.render.roundedRectangleBorder(
ASolidBrush { AColor::BLACK }, circle.position - *circle.radius, glm::vec2(circle.radius * 2.f),
circle.radius, 1);
}
}
setBlending#
Sets blending mode.
- Arguments
blendingnew blending mode
Blending Modes and Effects
The rendering engine supports multiple blending modes for advanced visual effects:
enum class Blending
Blending mode.
Terminology used in this documentation:
- Source color (S)
- Source color is a color of the brush (i.e. texture color matching current position) multiplied by the current renderer color, i.e. when drawing a black rectangle onto the white canvas the source color is black.
- Destination color (D)
- Destination color is a color of the framebuffer you're drawing to, i.e. when drawing a black rectangle onto the white canvas the destination color is white.
- S.rgb
- Source color without the alpha component.
- S.a
- Source's alpha component without the color itself.
- D.rgb
- Destination color without the alpha component.
- D.a
- Destination's alpha component without the color itself.
- Alpha-based
- Alpha-based blending mode is a blending mode that uses the alpha component in it's formula.
- Color-based
- Color-based blending mode is a blending mode that does not use the alpha component in it's formula.
| Constant | Description |
|---|---|
Blending::NORMAL
|
Normal blending.
|
Blending::ADDITIVE
|
Simply sums S and D colors.
|
Blending::INVERSE_DST
|
Inverses destination color and multiplies it with the source color.
|
Blending::INVERSE_SRC
|
Inverses source color and multiplies it with the destination color.
|
setColor#
void IRenderer::setColor(const AColor& color)
Sets the color which is multiplied with any brush. Unlike setColorForced, the new color is multiplied
by the previous color.
- Arguments
colorcolor
Examples:
examples/app/minesweeper/src/CellView.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
color = 0x808080ffu;
break;
}
context.render.setColor(color);
context.render.string({getWidth() / 3, (getHeight() - fs.size) / 2 + fs.getAscenderHeight()}, AString::number(count), fs);
}
}
}
setColorForced#
void IRenderer::setColorForced(const AColor& color)
Sets the color which is multiplied with any brush.
- Arguments
colorcolor
setRenderScale#
Controls the rendering scale of images for display only. Does not affect the actual visual appearance or geometry of shapes. Only impacts the sharpness and clarity of rendered images on screen.
setTransform#
Sets the transform matrix which is applicable for any figure. Unlike setTransformForced, the new
matrix is multiplied by the previous matrix.
- Arguments
transformtransform matrix
setTransformForced#
Sets the transform matrix which is applicable for any figure.
- Arguments
transformtransform matrix
setWindow#
Sets the window to render on.
- Arguments
windowtarget window
squareSector#
virtual void IRenderer::squareSector(const ABrush& brush, const glm::vec2& position, const glm::vec2& size, AAngleRadians begin, AAngleRadians end)
Draws sector in rectangle shape. The sector is drawn clockwise from begin to end angles.
- Arguments
brushbrush to usepositionrectangle position (px)sizerectangle size (px)beginbegin angle of the sectorendend angle of the sector
The method can be used as mask to ctx.render.roundedRect, creating arc shape.
string#
virtual void IRenderer::string(glm::vec2 position, const AString& string, const AFontStyle& fs = { })
Draws string.
- Arguments
positionstring baselinestringstring to renderfsfont style (optional)
This function is dramatically inefficient since it does symbol lookup for every character is the
string and does GPU buffer allocations. If you want to render the same string for several
times (frames), consider using the IRenderer::prerenderString function or high level views (such as
ALabel) instead.
Examples:
examples/app/minesweeper/src/CellView.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
break;
}
context.render.setColor(color);
context.render.string({getWidth() / 3, (getHeight() - fs.size) / 2 + fs.getAscenderHeight()}, AString::number(count), fs);
}
}
}
stub#
Draws stub (i.e., gray rectangle)
This can be used if implementation does not support or can't draw complex effects (i.e., blur)
translate#
Wrapper for setTransform applying matrix translate transformation.
- Arguments
offsetoffset in pixels to translate.
Examples:
examples/app/fractal/src/FractalView.cpp
Fractal Example - Fractal viewer application demonstrating usage of custom shaders.
void FractalView::onScroll(const AScrollEvent& event) {
AView::onScroll(event);
auto projectedPos = (glm::dvec2(event.origin) / glm::dvec2(getSize()) - glm::dvec2(0.5)) * 2.0;
projectedPos.x *= mAspectRatio;
mTransform = glm::translate(mTransform, glm::vec3 { projectedPos, 0.0 });
mTransform = glm::scale(mTransform, glm::vec3(1.0 - event.delta.y / 1000.0));
mTransform = glm::translate(mTransform, -glm::vec3 { projectedPos, 0.0 });
handleMatrixUpdated();