Replaced gli with libktx for 2D texture array loading sample

This commit is contained in:
Sascha Willems 2019-08-03 09:55:46 +02:00
parent 87042dc358
commit 660e93e0c4
2 changed files with 32 additions and 19 deletions

View file

@ -222,7 +222,7 @@ public:
// Calculate offset into staging buffer for the current mip lavel // Calculate offset into staging buffer for the current mip lavel
ktx_size_t offset; ktx_size_t offset;
assert(ktxTexture_GetImageOffset(ktxTexture, i, 0, 0, &offset) == KTX_SUCCESS); assert(ktxTexture_GetImageOffset(ktxTexture, i, 0, 0, &offset) == KTX_SUCCESS);
// Setup a buffer image copy structure for the current mip lavel // Setup a buffer image copy structure for the current mip level
VkBufferImageCopy bufferCopyRegion = {}; VkBufferImageCopy bufferCopyRegion = {};
bufferCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; bufferCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
bufferCopyRegion.imageSubresource.mipLevel = i; bufferCopyRegion.imageSubresource.mipLevel = i;

View file

@ -104,11 +104,16 @@ public:
void loadTextureArray(std::string filename, VkFormat format) void loadTextureArray(std::string filename, VkFormat format)
{ {
ktxResult result;
ktxTexture* ktxTexture;
#if defined(__ANDROID__) #if defined(__ANDROID__)
// Textures are stored inside the apk on Android (compressed) // Textures are stored inside the apk on Android (compressed)
// So they need to be loaded via the asset manager // So they need to be loaded via the asset manager
AAsset* asset = AAssetManager_open(androidApp->activity->assetManager, filename.c_str(), AASSET_MODE_STREAMING); AAsset* asset = AAssetManager_open(androidApp->activity->assetManager, filename.c_str(), AASSET_MODE_STREAMING);
assert(asset); if (!asset) {
vks::tools::exitFatal("Could not load texture from " + filename + "\n\nThe file may be part of the additional asset pack.\n\nRun \"download_assets.py\" in the repository root to download the latest version.", -1);
}
size_t size = AAsset_getLength(asset); size_t size = AAsset_getLength(asset);
assert(size > 0); assert(size > 0);
@ -116,16 +121,23 @@ public:
AAsset_read(asset, textureData, size); AAsset_read(asset, textureData, size);
AAsset_close(asset); AAsset_close(asset);
gli::texture2d_array tex2DArray(gli::load((const char*)textureData, size)); result = ktxTexture_CreateFromMemory(textureData, size, KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, target);
free(textureData);
#else #else
gli::texture2d_array tex2DArray(gli::load(filename)); if (!vks::tools::fileExists(filename)) {
vks::tools::exitFatal("Could not load texture from " + filename + "\n\nThe file may be part of the additional asset pack.\n\nRun \"download_assets.py\" in the repository root to download the latest version.", -1);
}
result = ktxTexture_CreateFromNamedFile(filename.c_str(), KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, &ktxTexture);
#endif #endif
assert(result == KTX_SUCCESS);
assert(!tex2DArray.empty()); // Get properties required for using and upload texture data from the ktx texture object
textureArray.width = ktxTexture->baseWidth;
textureArray.width = tex2DArray.extent().x; textureArray.height = ktxTexture->baseHeight;
textureArray.height = tex2DArray.extent().y; layerCount = ktxTexture->numLayers;
layerCount = tex2DArray.layers(); ktx_uint8_t *ktxTextureData = ktxTexture_GetData(ktxTexture);
ktx_size_t ktxTextureSize = ktxTexture_GetSize(ktxTexture);
VkMemoryAllocateInfo memAllocInfo = vks::initializers::memoryAllocateInfo(); VkMemoryAllocateInfo memAllocInfo = vks::initializers::memoryAllocateInfo();
VkMemoryRequirements memReqs; VkMemoryRequirements memReqs;
@ -135,7 +147,7 @@ public:
VkDeviceMemory stagingMemory; VkDeviceMemory stagingMemory;
VkBufferCreateInfo bufferCreateInfo = vks::initializers::bufferCreateInfo(); VkBufferCreateInfo bufferCreateInfo = vks::initializers::bufferCreateInfo();
bufferCreateInfo.size = tex2DArray.size(); bufferCreateInfo.size = ktxTextureSize;
// This buffer is used as a transfer source for the buffer copy // This buffer is used as a transfer source for the buffer copy
bufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; bufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
@ -155,29 +167,29 @@ public:
// Copy texture data into staging buffer // Copy texture data into staging buffer
uint8_t *data; uint8_t *data;
VK_CHECK_RESULT(vkMapMemory(device, stagingMemory, 0, memReqs.size, 0, (void **)&data)); VK_CHECK_RESULT(vkMapMemory(device, stagingMemory, 0, memReqs.size, 0, (void **)&data));
memcpy(data, tex2DArray.data(), tex2DArray.size()); memcpy(data, ktxTextureData, ktxTextureSize);
vkUnmapMemory(device, stagingMemory); vkUnmapMemory(device, stagingMemory);
// Setup buffer copy regions for array layers // Setup buffer copy regions for array layers
std::vector<VkBufferImageCopy> bufferCopyRegions; std::vector<VkBufferImageCopy> bufferCopyRegions;
size_t offset = 0;
// To keep this simple, we will only load layers and no mip level
for (uint32_t layer = 0; layer < layerCount; layer++) for (uint32_t layer = 0; layer < layerCount; layer++)
{ {
// Calculate offset into staging buffer for the current array layer
ktx_size_t offset;
assert(ktxTexture_GetImageOffset(ktxTexture, 0, layer, 0, &offset) == KTX_SUCCESS);
// Setup a buffer image copy structure for the current array layer
VkBufferImageCopy bufferCopyRegion = {}; VkBufferImageCopy bufferCopyRegion = {};
bufferCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; bufferCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
bufferCopyRegion.imageSubresource.mipLevel = 0; bufferCopyRegion.imageSubresource.mipLevel = 0;
bufferCopyRegion.imageSubresource.baseArrayLayer = layer; bufferCopyRegion.imageSubresource.baseArrayLayer = layer;
bufferCopyRegion.imageSubresource.layerCount = 1; bufferCopyRegion.imageSubresource.layerCount = 1;
bufferCopyRegion.imageExtent.width = static_cast<uint32_t>(tex2DArray[layer][0].extent().x); bufferCopyRegion.imageExtent.width = ktxTexture->baseWidth;
bufferCopyRegion.imageExtent.height = static_cast<uint32_t>(tex2DArray[layer][0].extent().y); bufferCopyRegion.imageExtent.height = ktxTexture->baseHeight;
bufferCopyRegion.imageExtent.depth = 1; bufferCopyRegion.imageExtent.depth = 1;
bufferCopyRegion.bufferOffset = offset; bufferCopyRegion.bufferOffset = offset;
bufferCopyRegions.push_back(bufferCopyRegion); bufferCopyRegions.push_back(bufferCopyRegion);
// Increase offset into staging buffer for next level / face
offset += tex2DArray[layer][0].size();
} }
// Create optimal tiled target image // Create optimal tiled target image
@ -271,6 +283,7 @@ public:
// Clean up staging resources // Clean up staging resources
vkFreeMemory(device, stagingMemory, nullptr); vkFreeMemory(device, stagingMemory, nullptr);
vkDestroyBuffer(device, stagingBuffer, nullptr); vkDestroyBuffer(device, stagingBuffer, nullptr);
ktxTexture_Destroy(ktxTexture);
} }
void loadTextures() void loadTextures()