Program Listing for File textureManager.cpp
↰ Return to documentation for file (PrismEngine/src/textureManager.cpp)
#include "textureManager.h"
#include "textureLoader.h"
namespace prism::PGC {
uint32_t TextureManager::addTexture(utils::Context* context, const std::string& texturePath) {
Texture texture = TextureLoader::load(context, texturePath);
if (texture.image == VK_NULL_HANDLE) {
return INVALID_TEXTURE;
}
uint32_t index = getNextAvailableIndex(context);
texture.bindlessIndex = index;
if (index >= context->textures.size()) {
context->textures.push_back(texture);
}
else {
context->textures[index] = texture;
}
updateDescriptors(context);
return index;
}
void TextureManager::removeTexture(utils::Context* context, uint32_t textureId) {
if (textureId == INVALID_TEXTURE || textureId >= context->textures.size()) {
return;
}
TextureLoader::cleanup(context, &context->textures[textureId]);
context->freeTextureIndices.push_back(textureId);
updateDescriptors(context);
}
void TextureManager::cleanup(utils::Context* context) {
for (uint32_t i = INVALID_TEXTURE+1; i < context->textures.size(); i++) {
auto& texture = context->textures[i];
if (texture.image != VK_NULL_HANDLE) {
TextureLoader::cleanup(context, &texture);
}
}
context->textures.clear();
context->freeTextureIndices.clear();
}
void TextureManager::updateDescriptors(utils::Context* context) {
if (context->textureDescriptorSet == VK_NULL_HANDLE) {
return;
}
std::vector<std::pair<uint32_t, VkDescriptorImageInfo>> validTextures;
for (uint32_t i = INVALID_TEXTURE+1; i < context->textures.size(); i++) {
if (context->textures[i].image != VK_NULL_HANDLE) {
VkDescriptorImageInfo imageInfo{};
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
imageInfo.imageView = context->textures[i].imageView;
imageInfo.sampler = context->textures[i].sampler;
validTextures.emplace_back(i, imageInfo);
}
}
if (validTextures.empty()) {
return;
}
std::vector<VkWriteDescriptorSet> descriptorWrites;
descriptorWrites.reserve(validTextures.size());
for (const auto& [index, imageInfo] : validTextures) {
VkWriteDescriptorSet descriptorWrite{};
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrite.dstSet = context->textureDescriptorSet;
descriptorWrite.dstBinding = 0;
descriptorWrite.dstArrayElement = index;
descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
descriptorWrite.descriptorCount = 1;
descriptorWrite.pImageInfo = &imageInfo;
descriptorWrites.push_back(descriptorWrite);
}
vkUpdateDescriptorSets(context->device,
static_cast<uint32_t>(descriptorWrites.size()),
descriptorWrites.data(), 0, nullptr);
}
uint32_t TextureManager::getNextAvailableIndex(utils::Context* context) {
if (!context->freeTextureIndices.empty()) {
uint32_t index = context->freeTextureIndices.back();
context->freeTextureIndices.pop_back();
return index >= INVALID_TEXTURE+1 ? index : getNextAvailableIndex(context);
}
return static_cast<uint32_t>(context->textures.size() > 0 ? context->textures.size() : INVALID_TEXTURE+1);
}
}