Closed Anecoz closed 11 months ago
Could probably use libktx for this.
Example for loading an image fro memory data:
#include <ktx.h>
#include <vkformat_enum.h>
ktxTexture2* texture;
ktxTextureCreateInfo createInfo;
KTX_error_code result;
ktx_uint32_t level, layer, faceSlice;
FILE* src;
ktx_size_t srcSize;
ktxBasisParams params = {0};
params.structSize = sizeof(params);
createInfo.glInternalformat = 0; //Ignored as we'll create a KTX2 texture.
createInfo.vkFormat = VK_FORMAT_R8G8B8A8_UNORM;
createInfo.baseWidth = 2048;
createInfo.baseHeight = 1024;
createInfo.baseDepth = 16;
createInfo.numDimensions = 3.
// Note: it is not necessary to provide a full mipmap pyramid.
createInfo.numLevels = log2(createInfo.baseWidth) + 1
createInfo.numLayers = 1;
createInfo.numFaces = 1;
createInfo.isArray = KTX_FALSE;
createInfo.generateMipmaps = KTX_FALSE;
result = ktxTexture2_Create(&createInfo,
KTX_TEXTURE_CREATE_ALLOC_STORAGE,
&texture);
src = // Open the file for the baseLevel image, slice 0 and
// read it into memory.
srcSize = // Query size of the file.
level = 0;
layer = 0;
faceSlice = 0;
result = ktxTexture_SetImageFromMemory(ktxTexture(texture),
level, layer, faceSlice,
src, srcSize);
And then transcoding to e.g. BC7:
#include <ktx.h>
// Load
ktxTexture2 *ktx_texture;
KTX_error_code result = ktxTexture_CreateFromNamedFile(file_name, KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, (ktxTexture**)&ktx_texture);
// Select format depending on support
ktx_transcode_fmt_e target_format = KTX_TTF_RGBA32;
if ((device_features.textureCompressionBC) && (fmt_supported(VK_FORMAT_BC7_SRGB_BLOCK)))
{
target_format = KTX_TTF_BC7_RGBA;
}
// Transcode
if (ktxTexture2_NeedsTranscoding(ktx_texture))
{
ktxTexture2_TranscodeBasis(ktx_texture, target_format, 0);
}
// Vulkan image format
VkFormat format = (VkFormat) ktx_texture->vkFormat;
// Upload
VK_CHECK(vkMapMemory(device, staging_memory, 0, memory_requirements.size, 0, (void **) &data));
memcpy(data, ktx_texture->pData, ktx_texture->dataSize);
Save and use textures in a compressed format.