Add a RenderTarget resource so the scene can render offscreen instead of straight to the swapchain. The editor uses it to show the scene inside the Viewport panel. - Rename AssetRegistry to ResourceRegistry (AssetTraits -> ResourceTraits, assets() -> resources()) and move the pools from engine/src/assets to engine/src/resources. It now covers non-asset GPU resources as well. - Replace loadMesh() with create<T>(...), and add create<RenderTarget>(), requestResize(), getExtent() and isAlive(). - Add RenderTarget and RenderTargetPool with RenderTargetHandle. Resizes are deferred and applied at the start of the next frame, when the GPU is idle. - Add Application::setSceneTarget(). With no target set, the scene still renders to the swapchain. With a target set, the scene renders offscreen and the swapchain receives only the UI. Frame extent and camera projection follow the target's size. - Add sophia::UI (Application::ui()) with image() and getTextureId() to draw a render target in an ImGui window, sizing the target to the available space. ImGuiRenderer now registers the target textures for this. - ViewportPanel takes the UI and a target, and draws the scene image in place of the flat background fill. - Update the testbed, the boids example, and the glossary for the rename.
7.2 KiB
Glossary
ResourceRegistry
A ResourceRegistry owns GPU-backed resources on the caller's behalf and hands out lightweight Handles instead of pointers or ownership.
Internally it's a collection of per-type pools, each responsible for one resource type:
ResourceRegistry
├── MeshPool → MeshHandle
├── TexturePool → TextureHandle (planned)
└── MaterialPool → MaterialHandle (planned)
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).
Typical lifecycle:
load<Mesh>(path) / create<Mesh>(...) → MeshHandle
│
get<Mesh>(handle) → const Mesh&
│
release<Mesh>(handle)
Think: "Where do I get 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's a generation-checked slot pool, the same shape ResourceRegistry's per-type pools use:
PanelRegistry
└── 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?"
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?"