From d90d02e4d627b7a849e803ad52288b42bf1a767d Mon Sep 17 00:00:00 2001 From: leblane Date: Fri, 28 Apr 2023 19:54:24 +0300 Subject: [PATCH] Add usage information and a screenshot --- README.md | 18 ++++++++++++++++++ Source/Main.cpp | 6 +++--- screenshot.webp | Bin 0 -> 14562 bytes 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 screenshot.webp diff --git a/README.md b/README.md index f2561f3..6315656 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ # TextureTaffy A utility to create compressed textures, in BC1 (DXT1), BC3 (DXT5), BC4, BC5, BC6(U)H and BC7 compression formats, with the [KTX File Format Version 2.0](https://registry.khronos.org/KTX/specs/2.0/ktxspec.v2.html) (KTX2) file format. +Multithreaded, uses ispc_texcomp for compression, and stb_image for image loading. + +![Screenshot](screenshot.webp) ## Requirements @@ -15,6 +18,21 @@ meson setup build [--buildtype=release] -Dcpp_std=c++17 meson compile -C build ``` +## Usage + +``` +Usage: TextureTaffy [cube|array] [input2, input3...] [fast|normal|slow|veryslow] +Formats: + BC1 - (DXT1) 5:6:5 Color, 1 bit alpha. 8 bytes per block. + BC1_SRGB - (DXT1) 5:6:5 Color, 1 bit alpha. 8 bytes per block. + BC4 - Greyscale, 8 bytes per block. + BC5 - 2x BC4 images. 16 bytes per block. + BC3 - (DXT5) BC1 Color, BC4 Alpha, 16 bytes per block. + BC3_SRGB - (DXT5) BC1 Color, BC4 Alpha, 16 bytes per block. + BC6H - 16 bit RGB, no alpha. Signed. 16 bytes per block. + BC7 - 8 bit RGBA - Good general purpose. 16 bytes per block. + BC7_SRGB - 8 bit RGBA - Good general purpose. 16 bytes per block. +``` ## Notes and limitations * Uses stb_image for image loading. Therefore only supports radiance HDR images, not OpenEXR. diff --git a/Source/Main.cpp b/Source/Main.cpp index 5f06ef2..7e0a646 100644 --- a/Source/Main.cpp +++ b/Source/Main.cpp @@ -41,14 +41,14 @@ const std::map> formats = {"BC7_SRGB", {"8 bit RGBA - Good general purpose. 16 bytes per block.", 16, vk::Format::eBc7SrgbBlock}} }; -const std::string usage = "Usage: TextureConverter [cube|array] [input2, input3...] [fast|normal|slow|veryslow]"; +const std::string usage = "[cube|array] [input2, input3...] [fast|normal|slow|veryslow]"; int main(int argc, char ** argv) { ISPCInit(); if (argc < 4) { - std::cout << usage << std::endl; + std::cout << "Usage: " << argv[0] << " " << usage << std::endl; std::cout << "Formats:" << std::endl; for (auto & formatName : formatOrder) { auto format = formats.at(formatName); @@ -91,7 +91,7 @@ int main(int argc, char ** argv) } if (numInputs < 1) { - std::cout << usage << std::endl; + std::cout << "Usage: " << argv[0] << usage << " " << std::endl; return 1; } diff --git a/screenshot.webp b/screenshot.webp new file mode 100644 index 0000000000000000000000000000000000000000..044229d578f6adcf347781c75dc16ecd7200b417 GIT binary patch literal 14562 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 IrGfl^0Jq}I9smFU literal 0 HcmV?d00001