5e1caabde6
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.
105 lines
3.1 KiB
C++
105 lines
3.1 KiB
C++
#include <sophia/resource_registry.hpp>
|
|
#include <sophia/util/assert.hpp>
|
|
|
|
#include "mesh.hpp"
|
|
#include "pools/mesh_pool.hpp"
|
|
#include "pools/render_target_pool.hpp"
|
|
#include "render_target.hpp"
|
|
|
|
namespace sophia {
|
|
|
|
class ResourceRegistry::Impl {
|
|
public:
|
|
Impl(Device& device, vk::Format renderTargetFormat)
|
|
: meshPool{device}, renderTargetPool{device, renderTargetFormat} {}
|
|
|
|
MeshPool meshPool;
|
|
RenderTargetPool renderTargetPool;
|
|
// TexturePool texturePool;
|
|
// MaterialPool materialPool;
|
|
};
|
|
|
|
ResourceRegistry::ResourceRegistry(Device& device, u32 renderTargetFormat)
|
|
: impl{std::make_unique<Impl>(
|
|
device, static_cast<vk::Format>(renderTargetFormat))} {}
|
|
|
|
ResourceRegistry::~ResourceRegistry() = default;
|
|
|
|
template <>
|
|
MeshHandle ResourceRegistry::load<Mesh>(const std::string& path) {
|
|
(void)path;
|
|
SOPHIA_ASSERT(false,
|
|
"Mesh::load(path) is not implemented yet - no model file "
|
|
"format is supported; build one via Mesh::Builder for now");
|
|
return MeshHandle{};
|
|
}
|
|
|
|
template <typename T>
|
|
typename ResourceTraits<T>::Handle load(const std::string&) {
|
|
static_assert(sizeof(T) == 0,
|
|
"load<T> is not implemented for this resource type");
|
|
}
|
|
|
|
template <>
|
|
void ResourceRegistry::release<Mesh>(MeshHandle handle) {
|
|
impl->meshPool.release(handle);
|
|
}
|
|
|
|
template <>
|
|
void ResourceRegistry::release<RenderTarget>(RenderTargetHandle handle) {
|
|
impl->renderTargetPool.release(handle);
|
|
}
|
|
|
|
template <>
|
|
const Mesh& ResourceRegistry::get<Mesh>(MeshHandle handle) const {
|
|
return impl->meshPool.get(handle);
|
|
}
|
|
|
|
MeshHandle ResourceRegistry::createResource(std::type_identity<Mesh>,
|
|
std::vector<CanvasVertex> vertices,
|
|
std::vector<u32> indices) {
|
|
Mesh::Builder builder{};
|
|
builder.vertices.reserve(vertices.size());
|
|
for (const CanvasVertex& vertex : vertices) {
|
|
builder.vertices.push_back({vertex.position, vertex.color});
|
|
}
|
|
builder.indices = std::move(indices);
|
|
|
|
return impl->meshPool.create(builder);
|
|
}
|
|
|
|
RenderTargetHandle ResourceRegistry::createResource(
|
|
std::type_identity<RenderTarget>, u32 width, u32 height) {
|
|
return impl->renderTargetPool.create(width, height);
|
|
}
|
|
|
|
void ResourceRegistry::requestResize(RenderTargetHandle handle, u32 width,
|
|
u32 height) {
|
|
impl->renderTargetPool.get(handle).requestResize(width, height);
|
|
}
|
|
|
|
glm::vec2 ResourceRegistry::getExtent(RenderTargetHandle handle) const {
|
|
vk::Extent2D extent =
|
|
std::as_const(impl->renderTargetPool).get(handle).getExtent();
|
|
return {static_cast<float>(extent.width), static_cast<float>(extent.height)};
|
|
}
|
|
|
|
bool ResourceRegistry::isAlive(RenderTargetHandle handle) const {
|
|
return impl->renderTargetPool.isAlive(handle);
|
|
}
|
|
|
|
RenderTarget& ResourceRegistry::getRenderTarget(RenderTargetHandle handle) {
|
|
return impl->renderTargetPool.get(handle);
|
|
}
|
|
|
|
const RenderTarget& ResourceRegistry::getRenderTarget(
|
|
RenderTargetHandle handle) const {
|
|
return std::as_const(impl->renderTargetPool).get(handle);
|
|
}
|
|
|
|
void ResourceRegistry::applyPendingResizes() {
|
|
impl->renderTargetPool.applyPendingResizes();
|
|
}
|
|
|
|
} // namespace sophia
|