Repository navigation
Testbed
The Testbed is the current executable project using NWBLot. Its application classes and helpers, including Testbed::Project, live in Testbed through the independent CoolStuff/Testbed/namespace.h; the six loader adapters remain in NWB. It links the loader/runtime pieces, scene/model/mesh/skinning/render/UI ECS systems, material/shader/mesh/model/skeleton assets, and the cooked engine/project assets.
It is a useful reference for how a project should use the loader and ECS runtime because it exercises:
- project callback API
- initial world creation
- render pass registration
- cooked volume loading
- shader archive resolution
- typed model/material references
- skinned mesh rendering
- custom UI (paint callbacks over
impl/ecs_ui/toolkit+impl/ecs_ui) - smoke-test window capture
Use the repository launcher from the checkout root (python3 on Linux):
python -m launcher testbed --build-only --config opt
python -m launcher testbed --config optBoth commands select the matching preset, configure when needed, and build Testbed with its pipeline and asset dependencies. --build-only stops before starting Testbed. The project owns CoolStuff/Testbed/launch.py; the root launcher discovers it through CoolStuff/launch.py. To build several targets or all targets, use python -m launcher build <targets...>. See Build and Verification for architecture, domain, custom directory, and test controls.
At startup it creates:
- active camera
- 45-degree directional light
- point light
- female skinned character
- white ground plane
- custom UI window (
NWB Testbedwindow with renderer/character notes plus widget galleries)
The active camera starts at 1280x900 default client size and looks back toward the model. The directional light uses a 45-degree pitch/yaw setup, while the point light provides a cool fill from above/right.
The main scene asset references are:
- character model:
project/characters/female/model - character material:
project/materials/mat_skinned_uv - ground plane model:
project/meshes/ground_plane/model - ground plane material:
project/materials/mat_white_opaque
The character and ground are model-driven ECS entities. Each owner entity has a ModelComponent and a RendererComponent; the model system expands the underlying static/skinned objects.
Testbed creates and verifies these systems:
MeshSystemRendererSystemModelSystemMeshSkinningSystemUiLayerSystem
These are bootstrap invariants. Testbed asserts that required scene entities and its ModelSystem are created successfully, rather than treating a broken fixed startup scene as a recoverable onStartup result. An assertion therefore signals invalid Testbed wiring, assets, or engine setup.
Render pass order:
MeshSkinningSystemRendererSystemUiLayerSystem
RendererSystem is also registered as a frame graph contributor.
Camera controls are project-level state:
-
W/S: forward/back -
A/D: left/right -
Shift: speed boost - right mouse drag: mouse look
The Testbed displays the selected mesh-processing path. The same authored mesh contract supplies native mesh rendering, eligible persistent indexed raster, or compute-emulated compute-plus-raster draws.
Project camera input yields to the UI when UiLayerSystem::wantsKeyboard()/wantsPointer() report capture. This prevents fly-camera movement while the user interacts with UI controls.
The Testbed UI is an ECS UiPaintComponent with a paint callback (drawCustomUiControls + drawUiControls in CoolStuff/Testbed/). The main window shows:
- renderer path note
- character note
with further widget galleries (combo/list/edit/image/popup/slider/radio/progress/skin-preview) beside it.
Combo, list, nested-popup, popup-tools, and search-combo galleries are backed by focused immutable list/source headers (ui_immutable_list_source.h, ui_nested_popup_source.h, ui_popup_tools_source.h, ui_search_combo_source.h); numeric-edit and text-area galleries cover the remaining input widgets.
The UI system follows the scene renderer in the render pass list and uses UiLayerPresentation::Scene. It prepares an independent display-linear layer; the renderer graph joins that layer with mapped scene color in final presentation rather than issuing a second backbuffer draw. The layer is frozen before recording.
Testbed requests HDR10 presentation from ConfigureProjectRuntime before device creation. On a surface that advertises the HDR10/PQ swapchain format, the renderer presents HDR10; otherwise it logs the reason and continues with SDR. Run Testbed with python -m launcher run testbed -- --sdr to force the SDR path. See HDR10 Presentation.
The Testbed target automatically cooks assets when nwb_asset_builder is available. The custom nwb_testbed_assets target runs pipeline/launch.py --skip-build over:
impl/assetsCoolStuff/Testbed/assets
The output is written to the runtime res directory. The runtime loader then mounts the cooked graphics volume from that directory.
The Testbed executable links asset modules with whole-archive linkage for mesh, skeleton, model, material, and shader assets so auto-registration can provide the needed codecs.
Testbed uses the same capability-driven renderer as every project:
- Windows ARM64 disables native mesh shaders by default, even when a driver advertises them. Eligible fixed engine meshes use persistent indexed raster; other draw sets use compute emulation. A project may explicitly opt in before graphics instance creation.
- Other supported targets may use native mesh shaders when the device supports them and the project configuration enables them.
- Ray tracing is optional. Hardware acceleration structures, ray queries, and ray-tracing pipelines are used only by paths whose required capabilities are available; software GPU BVHs cover shadow, GI, and caustic work otherwise.
- Texture upload chooses ASTC, BC, or an uncompressed format from actual Vulkan format support rather than CPU architecture.
The startup log records the selected adapter and active feature paths. See Platform and GPU Support and Renderer Feature Paths.
CTest target:
nwb_testbed_window_capture_smoke
The smoke runner starts the executable, waits for the NWB Testbed window, captures the frame, and writes beneath the selected configure preset:
__cmake/build/<configure-preset>/Testing/smoke/<config>/testbed_window_capture.bmp
On Linux, the capture runner requires DISPLAY and defaults NWB_LINUX_BACKEND to x11 unless the caller has already selected a backend. In headless environments, or when X11 cannot open the display, the smoke test skips with code 77 rather than failing.
The capture runner also covers renderer target replacement: --resize-client W H is opt-in (absent by default), uses 2.0 s settle intervals, rejects incompatible modes (application capture, explicit window handles, out-of-range sizes, non-positive or non-finite timeouts, sub-second resize settle), and refuses to combine resize with an active freeze-frame capture or a self-capture request. It waits for the original render, the runtime resize acknowledgement, and the final render before capturing.
On X11, the window search accepts either an exact requested title or the requested title followed by a space and runtime suffix, while still checking the process id when the window publishes one. This lets smoke projects share the same capture runner even when they append live diagnostic state to the title bar. Top-level X11 windows are tagged with _NET_WM_PID so headless XWayland teardown can find the exact window for a graceful WM_DELETE_WINDOW close even when the window is never mapped.
- Start Here
- Build and Verification
- Platform and GPU Support
- Graphics Device Selection
- Testbed
- Glossary
- Code Reading Guide
- Architecture
- Engine Concepts
- Asset Flow
- Frame Life Cycle
- Runtime Boot
- Project API
- Runtime and ECS
- CPU Task Scheduler
- Asset Pipeline
- Texture Conversion
- FBX to NWB Conversion
- Asset Types
- Cooked Volumes
- Filesystem
- Shader and Material System
- Mesh Model and Skinning