#include #include #include #include #include #include "resources/resource_registry.hpp" namespace sophia { template <> MeshHandle ResourceRegistryRef::load(const std::string& path) { (void)path; SOPHIA_ASSERT(false, "Mesh::load(path) is not implemented yet - no model file " "format is supported; build a MeshData instead"); return MeshHandle{}; } template <> TextureHandle ResourceRegistryRef::load(const std::string& path) { int width = 0; int height = 0; int channels = 0; // Always decode to RGBA8, whatever the file has. stbi_uc* pixels = stbi_load(path.c_str(), &width, &height, &channels, 4); if (pixels == nullptr) { log::fatal("failed to load texture {} - {}", path, stbi_failure_reason()); throw std::runtime_error("failed to load texture: " + path); } auto size = static_cast(width) * static_cast(height) * 4; TextureHandle handle = registry->texturePool.create( registry->device, static_cast(width), static_cast(height), std::span{pixels, size}); stbi_image_free(pixels); return handle; } template <> void ResourceRegistryRef::release(MeshHandle handle) { // Frames in flight may still be drawing it. registry->device.waitIdle(); registry->meshPool.release(handle); } template <> void ResourceRegistryRef::release(RenderTargetHandle handle) { registry->renderTargetPool.release(handle); } template <> void ResourceRegistryRef::release(TextureHandle handle) { SOPHIA_ASSERT(handle != registry->whiteTexture, "the built-in white texture cannot be released"); // Frames in flight may still be sampling it. registry->device.waitIdle(); registry->texturePool.release(handle); } MeshHandle ResourceRegistryRef::createResource(std::type_identity, const MeshData& data) { return registry->meshPool.create(registry->device, data); } RenderTargetHandle ResourceRegistryRef::createResource( std::type_identity, u32 width, u32 height) { return registry->renderTargetPool.create(width, height); } TextureHandle ResourceRegistryRef::createResource(std::type_identity, u32 width, u32 height, std::vector pixels) { return registry->texturePool.create(registry->device, width, height, std::span{pixels}); } void ResourceRegistryRef::requestResize(RenderTargetHandle handle, u32 width, u32 height) { registry->renderTargetPool.get(handle).requestResize(width, height); } glm::vec2 ResourceRegistryRef::getExtent(RenderTargetHandle handle) const { vk::Extent2D extent = registry->renderTargetPool.get(handle).getExtent(); return {static_cast(extent.width), static_cast(extent.height)}; } AABB ResourceRegistryRef::getBounds(MeshHandle handle) const { return registry->meshPool.get(handle).getBounds(); } bool ResourceRegistryRef::isAlive(MeshHandle handle) const { return registry->meshPool.isAlive(handle); } bool ResourceRegistryRef::isAlive(RenderTargetHandle handle) const { return registry->renderTargetPool.isAlive(handle); } glm::vec2 ResourceRegistryRef::getExtent(TextureHandle handle) const { const Texture& texture = registry->texturePool.get(handle); return {static_cast(texture.getWidth()), static_cast(texture.getHeight())}; } bool ResourceRegistryRef::isAlive(TextureHandle handle) const { return registry->texturePool.isAlive(handle); } } // namespace sophia