diff --git a/makefile b/makefile index cfd80cbd4..f583e7891 100644 --- a/makefile +++ b/makefile @@ -276,4 +276,8 @@ tools/bin/$(OS)/geometryc$(EXE): .build/projects/$(BUILD_PROJECT_DIR) $(SILENT) $(MAKE) -C .build/projects/$(BUILD_PROJECT_DIR) -f geometryc.make config=$(BUILD_TOOLS_CONFIG) $(SILENT) cp .build/$(BUILD_OUTPUT_DIR)/bin/geometryc$(BUILD_TOOLS_SUFFIX)$(EXE) $(@) -tools: tools/bin/$(OS)/shaderc$(EXE) tools/bin/$(OS)/geometryc$(EXE) +tools/bin/$(OS)/texturec$(EXE): .build/projects/$(BUILD_PROJECT_DIR) + $(SILENT) $(MAKE) -C .build/projects/$(BUILD_PROJECT_DIR) -f texturec.make config=$(BUILD_TOOLS_CONFIG) + $(SILENT) cp .build/$(BUILD_OUTPUT_DIR)/bin/texturec$(BUILD_TOOLS_SUFFIX)$(EXE) $(@) + +tools: tools/bin/$(OS)/shaderc$(EXE) tools/bin/$(OS)/geometryc$(EXE) tools/bin/$(OS)/texturec$(EXE) diff --git a/scripts/tools.mk b/scripts/tools.mk index 749cb742e..fec2885b7 100644 --- a/scripts/tools.mk +++ b/scripts/tools.mk @@ -24,3 +24,4 @@ endif SHADERC:="$(THISDIR)../tools/bin/$(OS)/shaderc" GEOMETRYC:="$(THISDIR)../tools/bin/$(OS)/geometryc" +TEXTUREC:="$(THISDIR)../tools/bin/$(OS)/texturec" diff --git a/src/image.cpp b/src/image.cpp index 737f482be..d8e16ae1f 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -193,6 +193,14 @@ namespace bgfx ; } + bool isValid(TextureFormat::Enum _format) + { + return _format != TextureFormat::Unknown + && _format != TextureFormat::UnknownDepth + && _format != TextureFormat::Count + ; + } + uint8_t getBitsPerPixel(TextureFormat::Enum _format) { return s_imageBlockInfo[_format].bitsPerPixel; @@ -213,6 +221,23 @@ namespace bgfx return s_textureFormatName[_format]; } + TextureFormat::Enum getFormat(const char* _name) + { + for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii) + { + const TextureFormat::Enum fmt = TextureFormat::Enum(ii); + if (isValid(fmt) ) + { + if (0 == bx::stricmp(s_textureFormatName[ii], _name) ) + { + return fmt; + } + } + } + + return TextureFormat::Unknown; + } + uint32_t imageGetSize(TextureFormat::Enum _format, uint16_t _width, uint16_t _height, uint16_t _depth, bool _cubeMap, uint8_t _numMips) { const ImageBlockInfo& blockInfo = getBlockInfo(_format); diff --git a/src/image.h b/src/image.h index 04bb12680..6f43ebea5 100644 --- a/src/image.h +++ b/src/image.h @@ -66,25 +66,31 @@ namespace bgfx uint8_t encoding; }; - /// + /// Returns true if texture format is compressed. bool isCompressed(TextureFormat::Enum _format); - /// + /// Returns true if texture format is uncompressed. bool isColor(TextureFormat::Enum _format); - /// + /// Returns true if texture format is depth. bool isDepth(TextureFormat::Enum _format); - /// + /// Returns true if texture format is valid. + bool isValid(TextureFormat::Enum _format); + + /// Returns bits per pixel. uint8_t getBitsPerPixel(TextureFormat::Enum _format); - /// + /// Returns texture block info. const ImageBlockInfo& getBlockInfo(TextureFormat::Enum _format); - /// + /// Converts format to string. const char* getName(TextureFormat::Enum _format); - /// + /// Converts string to format. + TextureFormat::Enum getFormat(const char* _name); + + /// Returns image size. uint32_t imageGetSize(TextureFormat::Enum _format, uint16_t _width, uint16_t _height, uint16_t _depth = 0, bool _cubeMap = false, uint8_t _numMips = 0); /// diff --git a/tools/geometryc/geometryc.cpp b/tools/geometryc/geometryc.cpp index 0314455b4..ead26234c 100644 --- a/tools/geometryc/geometryc.cpp +++ b/tools/geometryc/geometryc.cpp @@ -368,7 +368,7 @@ void help(const char* _error = NULL) "\n" "Supported input file types:\n" - " *.obj Wavefront\n" + " *.obj Wavefront\n" "\n" "Options:\n" diff --git a/tools/texturec/texturec.cpp b/tools/texturec/texturec.cpp index 82f04b6fc..fcb25f492 100644 --- a/tools/texturec/texturec.cpp +++ b/tools/texturec/texturec.cpp @@ -146,12 +146,32 @@ void help(const char* _error = NULL) "Copyright 2011-2015 Branimir Karadzic. All rights reserved.\n" "License: http://www.opensource.org/licenses/BSD-2-Clause\n\n" ); + + fprintf(stderr + , "Usage: texturec -f -o -t \n" + + "\n" + "Supported input file types:\n" + " *.png Portable Network Graphics\n" + " *.tga Targa\n" + " *.dds Direct Draw Surface\n" + " *.ktx Khronos Texture\n" + " *.pvr PowerVR\n" + + "\n" + "Options:\n" + " -f Input file path.\n" + " -o Output file path (file will be written in KTX format).\n" + " -t Output format type (BC1/2/3/4/5, ETC1, PVR14, etc.).\n" + " -m, --mips Generate mip-maps.\n" + + "\n" + "For additional information, see https://github.com/bkaradzic/bgfx\n" + ); } int main(int _argc, const char* _argv[]) { - using namespace bgfx; - bx::CommandLine cmdLine(_argc, _argv); if (cmdLine.hasArg('h', "help") ) @@ -160,7 +180,7 @@ int main(int _argc, const char* _argv[]) return EXIT_FAILURE; } - const char* inputFileName = cmdLine.findOption('i'); + const char* inputFileName = cmdLine.findOption('f'); if (NULL == inputFileName) { help("Input file must be specified."); @@ -183,54 +203,13 @@ int main(int _argc, const char* _argv[]) const bool mips = cmdLine.hasArg('m', "mips"); const char* type = cmdLine.findOption('t'); - TextureFormat::Enum format = TextureFormat::BGRA8; + bgfx::TextureFormat::Enum format = bgfx::TextureFormat::BGRA8; if (NULL != type) { - if (0 == bx::stricmp(type, "bc1") - || 0 == bx::stricmp(type, "dxt1") ) - { - format = TextureFormat::BC1; - } - else if (0 == bx::stricmp(type, "bc2") - || 0 == bx::stricmp(type, "dxt3") ) - { - format = TextureFormat::BC2; - } - else if (0 == bx::stricmp(type, "bc3") - || 0 == bx::stricmp(type, "dxt5") ) - { - format = TextureFormat::BC3; - } - else if (0 == bx::stricmp(type, "bc4") ) - { - format = TextureFormat::BC4; - } - else if (0 == bx::stricmp(type, "bc5") ) - { - format = TextureFormat::BC5; - } - else if (0 == bx::stricmp(type, "etc1") ) - { - format = TextureFormat::ETC1; - } - else if (0 == bx::stricmp(type, "bc6h") ) - { - format = TextureFormat::BC6H; - } - else if (0 == bx::stricmp(type, "bc7") ) - { - format = TextureFormat::BC7; - } - else if (0 == bx::stricmp(type, "ptc14") ) - { - format = TextureFormat::PTC14; - } - else if (0 == bx::stricmp(type, "ptc14a") ) - { - format = TextureFormat::PTC14A; - } - else + format = bgfx::getFormat(type); + + if (!isValid(format) ) { help("Invalid format specified."); return EXIT_FAILURE; @@ -238,86 +217,92 @@ int main(int _argc, const char* _argv[]) } uint32_t size = (uint32_t)bx::getSize(&reader); - const Memory* mem = alloc(size); + const bgfx::Memory* mem = bgfx::alloc(size); bx::read(&reader, mem->data, mem->size); bx::close(&reader); - uint8_t* decodedImage = NULL; - ImageContainer imageContainer; - - bool loaded = imageParse(imageContainer, mem->data, mem->size); - if (!loaded) { - int width = 0; - int height = 0; - int comp = 0; + using namespace bgfx; - decodedImage = stbi_load_from_memory( (uint8_t*)mem->data, mem->size, &width, &height, &comp, 4); - loaded = NULL != decodedImage; + uint8_t* decodedImage = NULL; + ImageContainer imageContainer; + bool loaded = imageParse(imageContainer, mem->data, mem->size); + if (!loaded) + { + int width = 0; + int height = 0; + int comp = 0; + + decodedImage = stbi_load_from_memory( (uint8_t*)mem->data, mem->size, &width, &height, &comp, 4); + loaded = NULL != decodedImage; + + if (loaded) + { + release(mem); + + mem = makeRef(decodedImage, width*height*4); + + imageContainer.m_data = mem->data; + imageContainer.m_size = mem->size; + imageContainer.m_offset = 0; + imageContainer.m_width = width; + imageContainer.m_height = height; + imageContainer.m_depth = 1; + imageContainer.m_format = bgfx::TextureFormat::RGBA8; + imageContainer.m_numMips = 1; + imageContainer.m_hasAlpha = true; + imageContainer.m_cubeMap = false; + imageContainer.m_ktx = false; + imageContainer.m_ktxLE = false; + imageContainer.m_srgb = false; + } + } + + BX_UNUSED(mips); if (loaded) { - release(mem); + bx::CrtAllocator allocator; + const Memory* output = NULL; - mem = makeRef(decodedImage, width*height*4); - - imageContainer.m_data = mem->data; - imageContainer.m_size = mem->size; - imageContainer.m_offset = 0; - imageContainer.m_width = width; - imageContainer.m_height = height; - imageContainer.m_depth = 1; - imageContainer.m_format = bgfx::TextureFormat::RGBA8; - imageContainer.m_numMips = 1; - imageContainer.m_hasAlpha = true; - imageContainer.m_cubeMap = false; - imageContainer.m_ktx = false; - imageContainer.m_ktxLE = false; - imageContainer.m_srgb = false; - } - } - - BX_UNUSED(mips); - if (loaded) - { - bx::CrtAllocator allocator; - const Memory* output = NULL; - - ImageMip mip; - if (imageGetRawData(imageContainer, 0, 0, mem->data, mem->size, mip) ) - { - uint32_t size = imageGetSize(TextureFormat::RGBA8, mip.m_width, mip.m_height); - uint8_t* rgba = (uint8_t*)BX_ALLOC(&allocator, size); - - imageDecodeToRgba8(rgba, mip.m_data, mip.m_width, mip.m_height, mip.m_width*mip.m_bpp/8, mip.m_format); - - imageContainer.m_size = imageGetSize(format, mip.m_width, mip.m_height); - imageContainer.m_format = format; - output = alloc(imageContainer.m_size); - - imageEncodeFromRgba8(output->data, rgba, mip.m_width, mip.m_height, format); - - BX_FREE(&allocator, rgba); - } - - if (NULL != output) - { - bx::CrtFileWriter writer; - if (0 == bx::open(&writer, outputFileName) ) + ImageMip mip; + if (imageGetRawData(imageContainer, 0, 0, mem->data, mem->size, mip) ) { - if (NULL != bx::stristr(outputFileName, ".ktx") ) - { - imageWriteKtx(&writer, imageContainer, output->data, output->size); - } + uint32_t size = imageGetSize(TextureFormat::RGBA8, mip.m_width, mip.m_height); + uint8_t* rgba = (uint8_t*)BX_ALLOC(&allocator, size); - bx::close(&writer); + imageDecodeToRgba8(rgba, mip.m_data, mip.m_width, mip.m_height, mip.m_width*mip.m_bpp/8, mip.m_format); + + imageContainer.m_size = imageGetSize(format, mip.m_width, mip.m_height); + imageContainer.m_format = format; + output = alloc(imageContainer.m_size); + + // bgfx::imageRgba8Downsample2x2(width, height, pitch, data, data); + + imageEncodeFromRgba8(output->data, rgba, mip.m_width, mip.m_height, format); + + BX_FREE(&allocator, rgba); } - release(output); - } - } + if (NULL != output) + { + bx::CrtFileWriter writer; + if (0 == bx::open(&writer, outputFileName) ) + { + if (NULL != bx::stristr(outputFileName, ".ktx") ) + { + imageWriteKtx(&writer, imageContainer, output->data, output->size); + } - release(mem); + bx::close(&writer); + } + + release(output); + } + } + + release(mem); + } return EXIT_SUCCESS; }