#include "ModelManager.hpp" #include #include "Log/Log.hpp" ModelManager::StaticModel::StaticModel(const std::vector& vertices, const std::vector& indices, VkPhysicalDevice physical_device, VkDevice device): physical_device_(physical_device), device_(device) { } ModelManager::StaticModel::~StaticModel() { } VkVertexInputBindingDescription ModelManager::Vertex::get_binding_description() { VkVertexInputBindingDescription description; description.binding = 0; description.stride = sizeof(Vertex); description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; return description; } std::array ModelManager::Vertex::get_vertex_attribute_descriptions() { std::array descriptions; // Bind vertex loc descriptions[0].binding = 0; descriptions[0].location = 0; descriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT; descriptions[0].offset = offsetof(Vertex, pos); // Bind color descriptions[1].binding = 0; descriptions[1].location = 1; descriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT; descriptions[1].offset = offsetof(Vertex, color); return descriptions; } ModelManager::owner_counter::owner_counter(const owner_counter& other) : counter(other.counter.load()), model(other.model) { } unsigned int ModelManager::FNV1aHash(const char* buf) { unsigned int h_val = 0x811c9dc5; while (*buf) { h_val ^= static_cast(*buf++); h_val *= 0x01000193; } return h_val; } ModelManager::ModelManager(VkPhysicalDevice physical_device, VkDevice device): physical_device_(physical_device), device_(device) {} ModelManager::~ModelManager() { models.clear(); } ModelManager::StaticModel* ModelManager::LoadModel(const std::string& name) { if (name.empty()) return nullptr; unsigned int hash = FNV1aHash(name.c_str()); auto counter = models.find(hash); if (counter != models.cend()) { ++counter->second.counter; return counter->second.model; } Loging::Log("Load new model: " + name); std::vector vertices; std::vector indices; // Load model_data owner_counter new_counter; new_counter.counter.store(1); new_counter.model = new StaticModel(vertices, indices, physical_device_, device_); models.try_emplace(hash, new_counter); return new_counter.model; } void ModelManager::FreeModel(const std::string& name) { if (name.empty()) return; unsigned int hash = FNV1aHash(name.c_str()); auto counter = models.find(hash); --counter->second.counter; StaticModel* model = counter->second.model; if (counter->second.counter.load() == 0) { Loging::Log("Free model: " + name); models.erase(hash); delete model; } }