.. _program_listing_file_PrismEngine_src_textureManager.cpp: Program Listing for File textureManager.cpp =========================================== |exhale_lsh| :ref:`Return to documentation for file ` (``PrismEngine\src\textureManager.cpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: 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> 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 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(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(context->textures.size() > 0 ? context->textures.size() : INVALID_TEXTURE+1); } }