Files
sophia/docs/glossary.md
2026-09-25 19:32:33 -07:00

9.0 KiB

Glossary

ResourceRegistry

A ResourceRegistry owns GPU-backed resources on the caller's behalf and hands out lightweight Handles instead of pointers or ownership. It is engine-internal: frontend code never sees it, and reaches it through a ResourceRegistryRef.

Internally it's a collection of per-type pools, each a Pool<T, Handle> (a generation-checked slot pool). A type that needs extra behaviour wraps its pool in a thin class instead:

ResourceRegistry
 ├── meshPool          Pool<Mesh, MeshHandle>
 ├── renderTargetPool  RenderTargetPool → RenderTargetHandle
 │                     (wraps Pool; waits for the GPU on release, applies resizes)
 ├── texturePool       (planned)
 └── materialPool      (planned)

Engine code (Application, ImGuiRenderer, SceneRenderer) uses the pools directly, e.g. resources.renderTargetPool.get(handle).

A Handle is a small (index, generation) pair. The index locates the slot in the pool; the generation is bumped when that slot is released, so a Handle kept around after release() is detected as stale instead of resolving to someone else's resource (or freed memory).

Think: "Where does the engine keep every GPU resource, and how does it look one up by handle?"

ResourceRegistryRef

A ResourceRegistryRef is the frontend's non-owning, cheap-to-copy view of the ResourceRegistry, returned by Application::resources(). It exposes only what frontend code needs and hands out no pools, so no Vulkan-facing types leak through the public API:

create<T>(...)   load<T>(path)   release<T>(handle)
requestResize(target, w, h)   getExtent(target)   isAlive(handle)

Typical lifecycle:

load<Mesh>(path) / create<Mesh>(...)  →  MeshHandle
                                        │
                        release<Mesh>(handle)

Think: "How do I create or release a GPU resource by handle, without owning its lifetime directly?"

Buffer

A Buffer is a linear region of GPU memory used to store arbitrary data.

Unlike an Image, which is designed for multidimensional image data, a buffer is essentially:

[ byte byte byte byte byte byte ... ]

Buffers commonly contain:

Vertex data Index data Uniform data Storage data Indirect draw commands

For example:

Vertex Buffer
┌─────────────────────────────────┐
│ Vertex │ Vertex │ Vertex │ ...  │
└─────────────────────────────────┘

In Vulkan, VkBuffer / vk::Buffer is a fundamental resource.

Think: "A linear chunk of GPU-accessible data."

Camera

A Camera defines how the scene is viewed and projected onto the screen.

It generally contains:

Position Orientation Projection parameters View matrix Projection matrix

For example:

Camera
 ├── Position
 ├── Rotation
 ├── Projection
 │    ├── Perspective
 │    └── Orthographic
 ├── View Matrix
 └── Projection Matrix

Think: "From where and how am I looking at the scene?"

Canvas

A Canvas is a coordinate/rendering space onto which things are drawn.

For UI, for example:

Canvas
┌──────────────────────────────┐
│                              │
│    ┌──────────────┐          │
│    │ Panel        │          │
│    └──────────────┘          │
│                              │
│              Button          │
│                              │
└──────────────────────────────┘

A canvas establishes things such as:

Dimensions Coordinate system Origin Scaling Potentially clipping

In a UI system, a Canvas is essentially:

The space in which UI elements are laid out and rendered.

Frame

Frame is context-dependent, but in a renderer it usually means one iteration of rendering the scene to produce one displayed image.

Layer

A Layer is a logical ordering/grouping of content.

For example:

Layer 0: Background Layer 1: World Layer 2: Characters Layer 3: Effects Layer 4: UI

Higher layers can be rendered over lower layers.

In a 2D engine, layers might determine draw order:

Background
    ↓
Tiles
    ↓
Player
    ↓
Particles
    ↓
UI

However, Layer is very engine-specific. In a 3D renderer it could instead represent a rendering category, visibility mask, or render-pass grouping.

Material

A Material describes how a surface should be rendered.

It usually combines:

Shader/pipeline configuration Textures Colors Numerical parameters

For example:

Material
 ├── Shader
 ├── Albedo Texture
 ├── Normal Texture
 ├── Roughness
 ├── Metallic
 └── Base Color

Then:

Mesh + Material + Transform
              ↓
           Renderer
              ↓
             GPU

A useful conceptual distinction is:

Mesh = what the object is shaped like. Material = how that shape should look.

Mesh

A Mesh is the geometric data used to describe the shape of an object.

Typically contains:

Vertex positions Normals Texture coordinates (UVs) Tangents Indices

For example, a cube mesh contains the vertices and triangles necessary to describe a cube.

Mesh
 ├── Vertices
 ├── Indices
 └── Vertex attributes
      ├── Position
      ├── Normal
      ├── UV
      └── Tangent

Think: "What shape is this object?"

Panel

A Panel is a rectangular UI region/container.

For example:

┌──────────────────────────────┐
│ Toolbar                      │
├───────────┬──────────────────┤
│           │                  │
│ Scene     │    Viewport      │
│           │                  │
├───────────┼──────────────────┤
│ Inspector │ Console          │
└───────────┴──────────────────┘

Each of those regions could be a panel.

A panel generally has:

Position Size Child elements UI contents Potentially its own rendering/context

This is primarily a UI concept, rather than a GPU concept.

PanelRegistry

A PanelRegistry owns Panels on the caller's behalf and hands out lightweight PanelHandles instead of pointers or ownership.

Internally it wraps a Pool<Panel, PanelHandle> (the same generation-checked slot pool ResourceRegistry uses, in sophia/util/pool.hpp) and adds the Panel-specific parts: lookup by type or name, and the default dock layout:

PanelRegistry
 └── Pool<Panel, PanelHandle>
      └── Slot { Panel, generation }  →  PanelHandle

Typical lifecycle:

add(panel) / emplace<T>(...)  →  PanelHandle
                                        │
                        get(handle) / get<T>(handle)  →  Panel& / T&
                                        │
                        remove(handle)

Each frame, update(frameInfo) calls onUpdate on every visible Panel it holds.

Think: "Where do I register or look up a UI panel by handle, without owning its lifetime directly?"

SceneRegistry

A SceneRegistry owns Scenes on the caller's behalf and hands out lightweight SceneHandles instead of pointers or ownership. Like PanelRegistry, it is owned by Application and reached from frontend code directly (scenes()), rather than through ResourceRegistryRef: scenes are CPU-side entity data, not GPU resources.

Internally it wraps a Pool<Scene, SceneHandle>:

SceneRegistry
 └── Pool<Scene, SceneHandle>
      └── Slot { Scene, generation }  →  SceneHandle

Typical lifecycle:

create()  →  SceneHandle
                  │
        get(handle)  →  Scene&
                  │
        release(handle)

Think: "Where do I create or look up a Scene by handle, without owning its lifetime directly?"

Sprite

A Sprite is a 2D renderable representation of an image, usually a rectangular region of a texture.

For example:

Texture Atlas
┌─────────────────────┐
│ Player │ Enemy      │
│        │            │
├────────┼────────────┤
│ Tree   │ Rock       │
└─────────────────────┘

A sprite might reference only the Player region of that texture.

A useful engine abstraction might be:

Sprite {
    Texture* texture;
    Rect uv;
}

Think: "Which 2D picture/region am I drawing?"

Texture

A Texture is image data intended to be used by a shader.

It can represent:

Color/albedo Normal maps Roughness Metallic values Masks Height maps etc.

A texture doesn't necessarily have to be displayed directly.

Texture → Shader → Material/Object

Think: "What image/data does the shader sample?"