Loading fireEngine’s first animated glTF scene
This release takes the Vulkan-free asset, scene, and preparation boundaries established in 0.7 and proves them against real imported content. The procedural triangle has been replaced by Khronos Group’s AnimatedCube glTF sample, loaded from external files, textured, animated, depth-tested, and kept running while presentation resources are recreated.
A new format-neutral SceneContent composition groups render assets, scene hierarchy, and reusable animation data without making glTF their long-lived owner. GltfLoader uses fastgltf and stb behind implementation boundaries to import a deliberately constrained glTF 2.0 subset: external buffers and PNG images, TRS nodes, indexed triangle primitives, positions, texture coordinates, base-color materials, samplers, and linear rotation channels. Unsupported required extensions, primitive modes, accessors, and animation paths fail explicitly.
The graphics descriptions now include decoded RGBA8 images, textures with filtering and wrapping behavior, optional material texture references, and texture coordinates. Render preparation follows their transitive dependencies so only resources referenced by the current scene are selected for GPU compilation.
The renderer compiles decoded images into device-local sRGB images through staging uploads and Synchronization 2 transitions. Image views and samplers remain alive with their allocations, while a persistent one-pixel white texture supports materials without a base-color texture. The renamed scene shader samples the texture and multiplies it by the material and vertex color factors.
AnimatedCube is rendered through a fixed perspective camera with an extent-derived aspect ratio. An extent-matched depth attachment is selected from supported formats, cleared and transitioned each frame, and used with depth testing, depth writes, and back-face culling.
Imported quaternion channels now drive scene-node rotations. Playback supports normalized shortest-arc interpolation, stable keyframe boundaries, looping and clamping, while transform-only animation changes continue to reuse the existing render-preparation plan and compiled GPU resources.
Swapchain recreation is now a normal renderer operation rather than a reason to exit. The swapchain, depth buffer, compatible pipeline, per-image semaphores, and presentation fences form one replaceable presentation state. Resize, suboptimal, and out-of-date results trigger recreation; minimized zero-sized windows wait for events without spinning; and the projection is refreshed for the replacement extent.
Presentation retirement uses the KHR or equivalent EXT swapchain-maintenance path. Per-image presentation fences prove when retired swapchains and semaphores are no longer in use by the presentation engine, covering a lifetime that deviceWaitIdle() alone does not guarantee.
The final integration pass extracted compiled scene resources and depth-buffer implementation from renderer.cpp. CompiledResources now owns images, samplers, meshes, fallback resources, upload machinery, and render-object lookup, while DepthBuffer remains correctly scoped to presentation lifetime.
Included in this release
- A committed, CC0-attributed Khronos AnimatedCube glTF asset.
- Deterministic build-tree paths for runtime assets and compiled shaders.
- Vec2, Quaternion, decomposed Transform, camera, and projection mathematics.
- Robust normalization across extreme finite floating-point magnitudes.
- Stable scene-local node identities and lookup.
- Vulkan-free ImageData, Texture, animation, and animator descriptions.
- Typed image, texture, animation, and scene-node identifiers.
- Format-neutral SceneContent.
- A constrained fastgltf-based JSON glTF loader.
- External buffer and image resolution relative to the source glTF.
- Accessor-aware position, UV, and index extraction.
- Unsigned 16-bit and 32-bit index support.
- Explicit rejection of unsupported required glTF data.
- stb-based RGBA8 image decoding behind an internal boundary.
- Transitive image and texture dependency selection during preparation.
- VMA-backed device-local images and staging uploads.
- Synchronization 2 transfer and shader-read image transitions.
- Combined image-sampler push descriptors.
- A persistent white fallback texture for untextured materials.
- A renamed scene.slang shader for the imported-scene path.
- A fixed perspective camera and extent-derived projection.
- Supported depth-format selection and depth-tested dynamic rendering.
- Back-face culling with corrected glTF/Vulkan winding.
- Linear quaternion animation playback with looping and clamping.
- Animation updates that do not invalidate render preparation.
- Replaceable swapchain-dependent presentation state.
- Resize, minimize, restore, suboptimal, and out-of-date handling.
- KHR or EXT presentation fences for safe swapchain retirement.
- Preservation of compiled meshes and textures across recreation.
- Focused CompiledResources and DepthBuffer implementation types.
- Separate public API and internal implementation Doxygen boundaries.
- Four bounded device scenarios covering animation, repeated preparation, fallback texturing, and recreation.
- Debug synchronization-validation variants and validation-error-aware CTest failures.
- Serialized Vulkan scenarios for reliable software-driver execution.
- 47 device-free Catch2 tests plus six device-test registrations, for 53 CTest tests in total.
- Linux device testing through Xvfb and Lavapipe, plus macOS and Windows build coverage.
- fastgltf 0.9.0 and stb 2024-07-29.
- Project and package versions updated to 0.8.0.
The supported content path remains intentionally small. Version 0.8 does not add lighting, metallic-roughness shading, normal maps, skinning, animation blending, mipmaps, multiple frames in flight, a pipeline cache, or a render graph. Its purpose is one complete and validated vertical slice: imported content moving through the engine’s asset, scene, animation, preparation, compilation, frame, and presentation boundaries without collapsing those responsibilities back into the renderer.