How to save 3D Texture? #598
-
Hey, Here is a streamlined code snippet I'm using to save my data as a 3D texture: // Write a KTX(1) Texture
// In: 'input' vector as float, 'size' struct for dimensions
ktxTexture1* texture;
ktxTextureCreateInfo createInfo;
KTX_error_code result;
createInfo.glInternalformat = (ktx_uint32_t) gl::GLenum::GL_RGBA32F;
createInfo.baseWidth = size.x;
createInfo.baseHeight = size.y;
createInfo.baseDepth = size.z;
createInfo.numDimensions = (size.z > 1) ? 3 : 2;
createInfo.numLevels = 1;
createInfo.numLayers = 1;
createInfo.numFaces = 1;
createInfo.isArray = KTX_FALSE;
createInfo.generateMipmaps = KTX_FALSE;
result = ktxTexture1_Create(&createInfo,
KTX_TEXTURE_CREATE_ALLOC_STORAGE,
&texture);
ktx_size_t srcSize = input.size() * sizeof(float);
uint8_t* src = (uint8_t*)input.data();
result = ktxTexture_SetImageFromMemory(ktxTexture(texture), 0, 0, 0, src, srcSize);
ktxTexture_WriteToNamedFile(ktxTexture(texture), "test.ktx");
ktxTexture_Destroy(ktxTexture(texture)); For loading this data I do basically this: // Load a KTX(1) Texture
ktxTexture1* texture;
KTX_error_code result;
result = ktxTexture_CreateFromNamedFile("test.ktx",
KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT,
&ktxTexture(texture));
std::vector<float> out(texture->dataSize / sizeof(float));
float* fData = reinterpret_cast<float*>(texture->pData);
out.assign(fData, fData + out.size());
return out; Help is much appreciated, as for 2D data everything works fine and when it becomes 3D the data is rubbish when I load it again. External tools like AMD's Compressonator also load and display my saved 2D KTX files fine, whereas for my 3D textures they only recognize a Depth of 1 (according to their source info view) and display nothing. Thanks. Edit: Also when I load my texture using above code Solution (thanks @MarkCallow): // This worked
texture->pData = reinterpret_cast<uint8_t*>(input.data());
ktxTexture_WriteToNamedFile(ktxTexture(texture), path);
texture->pData = nullptr;
ktxTexture_Destroy(ktxTexture(texture)); // And this worked
uint64_t slice_elements = input.size() / createInfo.baseDepth;
for (uint32_t z = 0; z < createInfo.baseDepth; z++) {
ktx_size_t srcSize;
uint8_t* src;
srcSize = input.data_size / createInfo.baseDepth;
src = reinterpret_cast<uint8_t*>(input.data() + z * slice_elements);
result = ktxTexture_SetImageFromMemory(ktxTexture(texture), 0, 0, z, src, srcSize);
if (result)
return false;
}
ktxTexture_WriteToNamedFile(ktxTexture(texture), path);
ktxTexture_Destroy(ktxTexture(texture)); |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 6 replies
-
What version of libktx are you using? I think you will find that I have no idea why Nothing to do with your problem but why you want to use the KTX 1.0 format? |
Beta Was this translation helpful? Give feedback.
What version of libktx are you using?
I think you will find that
ktxTexture_SetImageFromMemory
is returningKTX_INVALID_OPERATION
and so not setting any image data. The function is designed to set the data for a single image/depth slice. For 3D textures the third argument is theslice
to set. The function checks the expected size of an image and, ifsrcSize
is different, raisesKTX_INVALID_OPERATION
. For setting the all the images/slices at once, you should use thepData
pointer as you are in your loader.I have no idea why
baseDepth
is 1. I cannot reproduce that.Nothing to do with your problem but why you want …