diff --git a/src/image.cpp b/src/image.cpp index 499b54f7..6dcedc53 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -2293,10 +2293,10 @@ namespace bgfx { for (uint32_t xx = 0; xx < width; ++xx) { - decodeBlockDxt45A(temp+1, src); - src += 8; decodeBlockDxt45A(temp+2, src); src += 8; + decodeBlockDxt45A(temp+1, src); + src += 8; for (uint32_t ii = 0; ii < 16; ++ii) { @@ -2512,10 +2512,10 @@ namespace bgfx { uint8_t temp[16*4]; - decodeBlockDxt45A(temp+1, src); - src += 8; decodeBlockDxt45A(temp+2, src); src += 8; + decodeBlockDxt45A(temp+1, src); + src += 8; for (uint32_t ii = 0; ii < 16; ++ii) { @@ -2523,7 +2523,7 @@ namespace bgfx float ny = temp[ii*4+1]*2.0f/255.0f - 1.0f; float nz = sqrtf(1.0f - nx*nx - ny*ny); - const uint32_t offset = (yy + ii/4)*_pitch + (xx*4 + ii%4)*16; + const uint32_t offset = (yy*4 + ii/4)*_width*16 + (xx*4 + ii%4)*16; float* block = (float*)&dst[offset]; block[0] = nx; block[1] = ny; diff --git a/tools/texturec/texturec.cpp b/tools/texturec/texturec.cpp index 3bee4fe7..72b2c6f5 100644 --- a/tools/texturec/texturec.cpp +++ b/tools/texturec/texturec.cpp @@ -136,11 +136,11 @@ namespace bgfx } } - void imageEncodeFromRgba32f(void* _dst, const void* _src, uint32_t _width, uint32_t _height, uint8_t _format) + void imageEncodeFromRgba32f(bx::AllocatorI* _allocator, void* _dst, const void* _src, uint32_t _width, uint32_t _height, uint8_t _format) { TextureFormat::Enum format = TextureFormat::Enum(_format); - const float* src = (const float*)_src; + const uint8_t* src = (const uint8_t*)_src; switch (format) { @@ -151,19 +151,38 @@ namespace bgfx { for (uint32_t xx = 0; xx < _width; ++xx) { - const uint32_t offset = (yy*_width + xx) * 4; - const float* input = &src[offset]; - uint8_t* output = &dst[offset]; - output[0] = uint8_t( (input[0]*0.5f + 0.5f)*255.0f + 0.5f); - output[1] = uint8_t( (input[1]*0.5f + 0.5f)*255.0f + 0.5f); - output[2] = uint8_t( (input[2]*0.5f + 0.5f)*255.0f + 0.5f); - output[3] = uint8_t( (input[3]*0.5f + 0.5f)*255.0f + 0.5f); + const uint32_t offset = yy*_width + xx; + const float* input = (const float*)&src[offset * 16]; + uint8_t* output = &dst[offset * 4]; + output[0] = uint8_t(input[0]*255.0f + 0.5f); + output[1] = uint8_t(input[1]*255.0f + 0.5f); + output[2] = uint8_t(input[2]*255.0f + 0.5f); + output[3] = uint8_t(input[3]*255.0f + 0.5f); } } } break; case TextureFormat::BC5: + { + uint8_t* temp = (uint8_t*)BX_ALLOC(_allocator, _width*_height*4); + for (uint32_t yy = 0; yy < _height; ++yy) + { + for (uint32_t xx = 0; xx < _width; ++xx) + { + const uint32_t offset = yy*_width + xx; + const float* input = (const float*)&src[offset * 16]; + uint8_t* output = &temp[offset * 4]; + output[0] = uint8_t(input[0]*255.0f + 0.5f); + output[1] = uint8_t(input[1]*255.0f + 0.5f); + output[2] = uint8_t(input[2]*255.0f + 0.5f); + output[3] = uint8_t(input[3]*255.0f + 0.5f); + } + } + + imageEncodeFromRgba8(_dst, temp, _width, _height, _format); + BX_FREE(_allocator, temp); + } break; default: @@ -171,6 +190,54 @@ namespace bgfx } } + void imageRgba32f11to01(void* _dst, uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _src) + { + const uint8_t* src = (const uint8_t*)_src; + uint8_t* dst = (uint8_t*)_dst; + + for (uint32_t yy = 0; yy < _height; ++yy) + { + for (uint32_t xx = 0; xx < _width; ++xx) + { + const uint32_t offset = yy*_pitch + xx * 16; + const float* input = (const float*)&src[offset]; + float* output = (float*)&dst[offset]; + output[0] = input[0]*0.5f + 0.5f; + output[1] = input[1]*0.5f + 0.5f; + output[2] = input[2]*0.5f + 0.5f; + output[3] = input[3]*0.5f + 0.5f; + } + } + } + + const Memory* imageAlloc(ImageContainer& _imageContainer, TextureFormat::Enum _format, uint16_t _width, uint16_t _height, uint16_t _depth = 0, bool _cubeMap = false, bool _mips = false) + { + const uint8_t numMips = _mips ? imageGetNumMips(_format, _width, _height) : 1; + uint32_t size = imageGetSize(_format, _width, _height, 0, false, numMips); + const Memory* image = alloc(size); + + _imageContainer.m_data = image->data; + _imageContainer.m_format = _format; + _imageContainer.m_size = image->size; + _imageContainer.m_offset = 0; + _imageContainer.m_width = _width; + _imageContainer.m_height = _height; + _imageContainer.m_depth = _depth; + _imageContainer.m_numMips = numMips; + _imageContainer.m_hasAlpha = false; + _imageContainer.m_cubeMap = _cubeMap; + _imageContainer.m_ktx = false; + _imageContainer.m_ktxLE = false; + _imageContainer.m_srgb = false; + + return image; + } + + void imageFree(const Memory* _memory) + { + release(_memory); + } + } // namespace bgfx void help(const char* _error = NULL) @@ -321,6 +388,7 @@ int main(int _argc, const char* _argv[]) uint32_t size = imageGetSize(TextureFormat::RGBA32F, mip.m_width, mip.m_height); temp = BX_ALLOC(&allocator, size); float* rgba = (float*)temp; + float* rgbaDst = (float*)BX_ALLOC(&allocator, size); imageDecodeToRgba32f(&allocator , rgba @@ -331,35 +399,39 @@ int main(int _argc, const char* _argv[]) , mip.m_format ); - for (uint32_t yy = 0; yy < mip.m_height; ++yy) + if (TextureFormat::BC5 != mip.m_format) { - for (uint32_t xx = 0; xx < mip.m_width; ++xx) + for (uint32_t yy = 0; yy < mip.m_height; ++yy) { - const uint32_t offset = (yy*mip.m_width + xx) * 4; - float* inout = &rgba[offset]; - inout[0] = inout[0] * 2.0f/255.0f - 1.0f; - inout[1] = inout[1] * 2.0f/255.0f - 1.0f; - inout[2] = inout[2] * 2.0f/255.0f - 1.0f; - inout[3] = inout[3] * 2.0f/255.0f - 1.0f; + for (uint32_t xx = 0; xx < mip.m_width; ++xx) + { + const uint32_t offset = (yy*mip.m_width + xx) * 4; + float* inout = &rgba[offset]; + inout[0] = inout[0] * 2.0f/255.0f - 1.0f; + inout[1] = inout[1] * 2.0f/255.0f - 1.0f; + inout[2] = inout[2] * 2.0f/255.0f - 1.0f; + inout[3] = inout[3] * 2.0f/255.0f - 1.0f; + } } } - imageContainer.m_numMips = numMips; - imageContainer.m_size = imageGetSize(format, mip.m_width, mip.m_height, 0, false, numMips); - imageContainer.m_format = format; - output = alloc(imageContainer.m_size); + output = imageAlloc(imageContainer, format, mip.m_width, mip.m_height, 0, false, mips); - imageEncodeFromRgba32f(output->data, rgba, mip.m_width, mip.m_height, format); + imageRgba32f11to01(rgbaDst, mip.m_width, mip.m_height, mip.m_width*16, rgba); + imageEncodeFromRgba32f(&allocator, output->data, rgbaDst, mip.m_width, mip.m_height, format); for (uint8_t lod = 1; lod < numMips; ++lod) { imageRgba32fDownsample2x2NormalMap(mip.m_width, mip.m_height, mip.m_width*16, rgba, rgba); + imageRgba32f11to01(rgbaDst, mip.m_width, mip.m_height, mip.m_width*16, rgba); ImageMip dstMip; imageGetRawData(imageContainer, 0, lod, output->data, output->size, dstMip); uint8_t* data = const_cast(dstMip.m_data); - imageEncodeFromRgba32f(data, rgba, dstMip.m_width, dstMip.m_height, format); + imageEncodeFromRgba32f(&allocator, data, rgbaDst, dstMip.m_width, dstMip.m_height, format); } + + BX_FREE(&allocator, rgbaDst); } else { @@ -375,10 +447,7 @@ int main(int _argc, const char* _argv[]) , mip.m_format ); - imageContainer.m_numMips = numMips; - imageContainer.m_size = imageGetSize(format, mip.m_width, mip.m_height, 0, false, numMips); - imageContainer.m_format = format; - output = alloc(imageContainer.m_size); + output = imageAlloc(imageContainer, format, mip.m_width, mip.m_height, 0, false, mips); imageEncodeFromRgba8(output->data, rgba, mip.m_width, mip.m_height, format); @@ -408,8 +477,13 @@ int main(int _argc, const char* _argv[]) bx::close(&writer); } + else + { + help("Failed to open output file."); + return EXIT_FAILURE; + } - release(output); + imageFree(output); } }