Appearance
Graphics, Images & Colors
Vulpis features a custom OpenGL rendering pipeline that handles everything from hardware-accelerated rounded rectangles to asynchronous texture streaming. This page covers how to style your UI using the Color API, how to display images, and how the engine intelligently manages GPU memory.
1. The Color API
Vulpis supports two primary ways to define colors in your UI styles: HEX Strings and RGBA Tables.
The engine natively parses these formats and applies them to properties like color (for text), BGColor (for backgrounds), and borderColor.
Supported Formats
- HEX Strings: Supports both standard 6-character (
"#RRGGBB") and 8-character with alpha ("#RRGGBBAA") formats. The#symbol is optional. - RGBA Tables: An array of integers from 0-255:
{ Red, Green, Blue, Alpha }. If Alpha is omitted, it defaults to255(fully opaque).
Example: Styling with Colors
lua
local el = require("utils.core.elements")
function ColorCard()
return el.VBox({
style = {
w = 300, h = 150,
padding = 20,
-- Using a HEX string for the background
BGColor = "#282c34",
-- Using an RGBA table for a 50% transparent white border
borderColor = { 255, 255, 255, 128 },
borderWidth = 2,
borderRadius = 10
},
children = {
el.Text({
text = "Hello, Colors!",
style = {
-- Using an 8-character HEX for 80% opacity text
color = "#61afefCC",
fontSize = 24
}
})
}
})
end2. Texture & Image Registry
Vulpis does not load images blindly. It routes all image requests through a native C++ TextureRegistry that handles asynchronous loading, caching, and automatic memory management.
How the Registry Works
- Async Loading: When you request an image, the UI thread never freezes. Vulpis loads local files or downloads web URLs on a background thread. While loading, the engine displays a pulsating skeleton loader automatically.
- Web & Local Caching: Web images (e.g.,
https://...) are downloaded and saved to your OS cache directory. Local assets are baked into compressed.vtexfiles for near-instant GPU upload. - Ref-Counting (Memory Management): The engine tracks exactly how many UI nodes are using a specific image. If you change an image's
srcor destroy the node, Vulpis automatically decreases the reference count. When the count hits zero, the texture is purged from GPU memory automatically.
Using the Image Element
The el.Image component is used to display standalone images. Local file paths are automatically resolved relative to your project root, and remote images can be loaded natively by providing a web URL.
lua
local el = require("utils.core.elements")
function AvatarDisplay()
return el.Image({
-- Works with local assets or web URLs!
src = "https://example.com/user_avatar.png",
style = {
w = 120, h = 120,
borderRadius = 60 -- Perfectly round avatar
}
})
endUsing Background Images (BGImage)
Any standard container (like Box, VBox, or HBox) can have a background image applied to it using the BGImage style property.
lua
local el = require("utils.core.elements")
function HeroBanner()
return el.Box({
style = {
w = "100%", h = 300,
-- Applies an image behind the children
BGImage = "textures/landscape.png",
alignItems = "center",
justifyContent = "center"
},
children = {
el.Text({ text = "Welcome to Vulpis", style = { color = "#FFFFFF" } })
}
})
end3. Object Fit (Scaling Images)
When an image's source file doesn't perfectly match the width and height you set in your UI, you need to tell Vulpis how to scale it.
You control this using the fit property for Image elements, and the BGFit property for background images.
Scaling Modes
fill(Default for Images): The image is stretched or squished to exactly match the width and height of the UI node, ignoring the original aspect ratio.cover(Default for BGImage): The image scales up to completely fill the UI node while maintaining its aspect ratio. Any excess parts of the image that overflow the boundaries are cleanly cropped off.contain: The image scales down so that the entire picture is visible inside the UI node without losing its aspect ratio, leaving empty space (letterboxing) on the sides or top if necessary.
Example: Object Fit in Action
lua
local el = require("utils.core.elements")
function ImageGallery()
local myImage = "https://example.com/user_avatar.png"
return el.VBox({
style = { gap = 20, overflow = "scroll", flexShrink = 1 },
children = {
el.Image({
src = myImage,
style = { w = 600, h = 300, fit = "fill" },
}),
el.Image({
src = myImage,
style = { w = 600, h = 300, fit = "cover" },
}),
el.Box({
style = {
w = 600,
h = 600,
BGColor = "#000000",
BGImage = myImage,
BGFit = "contain",
},
}),
},
})
end