|
@@ -21,34 +21,21 @@
|
|
|
#include <bx/bx.h>
|
|
|
#include <bx/commandline.h>
|
|
|
#include <bx/file.h>
|
|
|
-#include <bx/uint32_t.h>
|
|
|
|
|
|
#include <string>
|
|
|
|
|
|
#define BIMG_TEXTUREC_VERSION_MAJOR 1
|
|
|
-#define BIMG_TEXTUREC_VERSION_MINOR 15
|
|
|
+#define BIMG_TEXTUREC_VERSION_MINOR 18
|
|
|
+
|
|
|
+BX_ERROR_RESULT(TEXTRUREC_ERROR, BX_MAKEFOURCC('t', 'c', 0, 0) );
|
|
|
|
|
|
struct Options
|
|
|
{
|
|
|
- Options()
|
|
|
- : maxSize(UINT32_MAX)
|
|
|
- , edge(0.0f)
|
|
|
- , format(bimg::TextureFormat::Count)
|
|
|
- , quality(bimg::Quality::Default)
|
|
|
- , mips(false)
|
|
|
- , normalMap(false)
|
|
|
- , equirect(false)
|
|
|
- , iqa(false)
|
|
|
- , pma(false)
|
|
|
- , sdf(false)
|
|
|
- , alphaTest(false)
|
|
|
- {
|
|
|
- }
|
|
|
-
|
|
|
void dump()
|
|
|
{
|
|
|
DBG("Options:\n"
|
|
|
"\t maxSize: %d\n"
|
|
|
+ "\t mipSkip: %d\n"
|
|
|
"\t edge: %f\n"
|
|
|
"\t format: %s\n"
|
|
|
"\t mips: %s\n"
|
|
@@ -56,7 +43,12 @@ struct Options
|
|
|
"\t iqa: %s\n"
|
|
|
"\t pma: %s\n"
|
|
|
"\t sdf: %s\n"
|
|
|
+ "\t radiance: %s\n"
|
|
|
+ "\t equirect: %s\n"
|
|
|
+ "\t strip: %s\n"
|
|
|
+ "\t linear: %s\n"
|
|
|
, maxSize
|
|
|
+ , mipSkip
|
|
|
, edge
|
|
|
, bimg::getName(format)
|
|
|
, mips ? "true" : "false"
|
|
@@ -64,20 +56,28 @@ struct Options
|
|
|
, iqa ? "true" : "false"
|
|
|
, pma ? "true" : "false"
|
|
|
, sdf ? "true" : "false"
|
|
|
+ , radiance ? "true" : "false"
|
|
|
+ , equirect ? "true" : "false"
|
|
|
+ , strip ? "true" : "false"
|
|
|
+ , linear ? "true" : "false"
|
|
|
);
|
|
|
}
|
|
|
|
|
|
- uint32_t maxSize;
|
|
|
- float edge;
|
|
|
- bimg::TextureFormat::Enum format;
|
|
|
- bimg::Quality::Enum quality;
|
|
|
- bool mips;
|
|
|
- bool normalMap;
|
|
|
- bool equirect;
|
|
|
- bool iqa;
|
|
|
- bool pma;
|
|
|
- bool sdf;
|
|
|
- bool alphaTest;
|
|
|
+ uint32_t maxSize = UINT32_MAX;
|
|
|
+ uint32_t mipSkip = 0;
|
|
|
+ float edge = 0.0f;
|
|
|
+ bimg::TextureFormat::Enum format = bimg::TextureFormat::Count;
|
|
|
+ bimg::Quality::Enum quality = bimg::Quality::Default;
|
|
|
+ bimg::LightingModel::Enum radiance = bimg::LightingModel::Count;
|
|
|
+ bool mips = false;
|
|
|
+ bool normalMap = false;
|
|
|
+ bool equirect = false;
|
|
|
+ bool strip = false;
|
|
|
+ bool iqa = false;
|
|
|
+ bool pma = false;
|
|
|
+ bool sdf = false;
|
|
|
+ bool alphaTest = false;
|
|
|
+ bool linear = false;
|
|
|
};
|
|
|
|
|
|
void imageRgba32fNormalize(void* _dst, uint32_t _width, uint32_t _height, uint32_t _srcPitch, const void* _src)
|
|
@@ -90,12 +90,8 @@ void imageRgba32fNormalize(void* _dst, uint32_t _width, uint32_t _height, uint32
|
|
|
const float* rgba = (const float*)&src[0];
|
|
|
for (uint32_t xx = 0; xx < _width; ++xx, rgba += 4, dst += 16)
|
|
|
{
|
|
|
- float xyz[3];
|
|
|
-
|
|
|
- xyz[0] = rgba[0];
|
|
|
- xyz[1] = rgba[1];
|
|
|
- xyz[2] = rgba[2];
|
|
|
- bx::vec3Norm( (float*)dst, xyz);
|
|
|
+ const bx::Vec3 xyz = bx::load(rgba);
|
|
|
+ bx::store(dst, bx::normalize(xyz) );
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -161,16 +157,65 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
|
|
|
const bimg::ImageBlockInfo& inputBlockInfo = bimg::getBlockInfo(inputFormat);
|
|
|
const bimg::ImageBlockInfo& outputBlockInfo = bimg::getBlockInfo(outputFormat);
|
|
|
const uint32_t blockWidth = outputBlockInfo.blockWidth;
|
|
|
- const uint32_t blockHeight = outputBlockInfo.blockHeight;
|
|
|
- const uint32_t minBlockX = outputBlockInfo.minBlockX;
|
|
|
- const uint32_t minBlockY = outputBlockInfo.minBlockY;
|
|
|
- uint32_t outputWidth = bx::uint32_max(blockWidth * minBlockX, ( (input->m_width + blockWidth - 1) / blockWidth )*blockWidth);
|
|
|
- uint32_t outputHeight = bx::uint32_max(blockHeight * minBlockY, ( (input->m_height + blockHeight - 1) / blockHeight)*blockHeight);
|
|
|
- uint32_t outputDepth = input->m_depth;
|
|
|
-
|
|
|
- if (outputWidth > _options.maxSize
|
|
|
- || outputHeight > _options.maxSize
|
|
|
- || outputDepth > _options.maxSize)
|
|
|
+ const uint32_t blockHeight = outputBlockInfo.blockHeight;
|
|
|
+ const uint32_t minBlockX = outputBlockInfo.minBlockX;
|
|
|
+ const uint32_t minBlockY = outputBlockInfo.minBlockY;
|
|
|
+ uint32_t outputWidth = bx::max(blockWidth * minBlockX, ( (input->m_width + blockWidth - 1) / blockWidth )*blockWidth);
|
|
|
+ uint32_t outputHeight = bx::max(blockHeight * minBlockY, ( (input->m_height + blockHeight - 1) / blockHeight)*blockHeight);
|
|
|
+ uint32_t outputDepth = input->m_depth;
|
|
|
+
|
|
|
+ if (_options.mips
|
|
|
+ && _options.mipSkip != 0)
|
|
|
+ {
|
|
|
+ for (uint32_t ii = 0; ii < _options.mipSkip; ++ii)
|
|
|
+ {
|
|
|
+ outputWidth = bx::max(blockWidth * minBlockX, ( ( (outputWidth>>1) + blockWidth - 1) / blockWidth )*blockWidth);
|
|
|
+ outputHeight = bx::max(blockHeight * minBlockY, ( ( (outputHeight>>1) + blockHeight - 1) / blockHeight)*blockHeight);
|
|
|
+ outputDepth = bx::max(outputDepth>>1, 1u);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (_options.equirect)
|
|
|
+ {
|
|
|
+ if (outputDepth == 1
|
|
|
+ && outputWidth/2 == outputHeight)
|
|
|
+ {
|
|
|
+ if (outputWidth/2 > _options.maxSize)
|
|
|
+ {
|
|
|
+ outputWidth = _options.maxSize*4;
|
|
|
+ outputHeight = _options.maxSize*2;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ bimg::imageFree(input);
|
|
|
+
|
|
|
+ BX_ERROR_SET(_err, TEXTRUREC_ERROR, "Input image format is not equirectangular projection.");
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (_options.strip)
|
|
|
+ {
|
|
|
+ if (outputDepth == 1
|
|
|
+ && outputWidth/6 == outputHeight)
|
|
|
+ {
|
|
|
+ if (outputWidth/6 > _options.maxSize)
|
|
|
+ {
|
|
|
+ outputWidth = _options.maxSize*6;
|
|
|
+ outputHeight = _options.maxSize;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ bimg::imageFree(input);
|
|
|
+
|
|
|
+ BX_ERROR_SET(_err, TEXTRUREC_ERROR, "Input image format is not horizontal strip.");
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (outputWidth > _options.maxSize
|
|
|
+ || outputHeight > _options.maxSize
|
|
|
+ || outputDepth > _options.maxSize)
|
|
|
{
|
|
|
if (outputDepth > outputWidth
|
|
|
&& outputDepth > outputHeight)
|
|
@@ -204,12 +249,14 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
|
|
|
&& !_options.sdf
|
|
|
&& !_options.alphaTest
|
|
|
&& !_options.normalMap
|
|
|
- && !_options.equirect
|
|
|
+ && !(_options.equirect || _options.strip)
|
|
|
&& !_options.iqa
|
|
|
&& !_options.pma
|
|
|
+ && (bimg::LightingModel::Count == _options.radiance)
|
|
|
;
|
|
|
|
|
|
- if (needResize)
|
|
|
+ if (!_options.sdf
|
|
|
+ && needResize)
|
|
|
{
|
|
|
bimg::ImageContainer* src = bimg::imageConvert(_allocator, bimg::TextureFormat::RGBA32F, *input, false);
|
|
|
|
|
@@ -224,8 +271,18 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
|
|
|
, false
|
|
|
);
|
|
|
|
|
|
+ if (!_options.linear)
|
|
|
+ {
|
|
|
+ bimg::imageRgba32fToLinear(src);
|
|
|
+ }
|
|
|
+
|
|
|
bimg::imageResizeRgba32fLinear(dst, src);
|
|
|
|
|
|
+ if (!_options.linear)
|
|
|
+ {
|
|
|
+ bimg::imageRgba32fToGamma(dst);
|
|
|
+ }
|
|
|
+
|
|
|
bimg::imageFree(src);
|
|
|
bimg::imageFree(input);
|
|
|
|
|
@@ -261,13 +318,24 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
|
|
|
return output;
|
|
|
}
|
|
|
|
|
|
- if (_options.equirect)
|
|
|
+ if (_options.equirect
|
|
|
+ || _options.strip)
|
|
|
{
|
|
|
bimg::ImageContainer* src = bimg::imageConvert(_allocator, bimg::TextureFormat::RGBA32F, *input);
|
|
|
bimg::imageFree(input);
|
|
|
|
|
|
- bimg::ImageContainer* dst = bimg::imageCubemapFromLatLongRgba32F(_allocator, *src, true, _err);
|
|
|
- bimg::imageFree(src);
|
|
|
+ bimg::ImageContainer* dst;
|
|
|
+
|
|
|
+ if (outputWidth/2 == outputHeight)
|
|
|
+ {
|
|
|
+ dst = bimg::imageCubemapFromLatLongRgba32F(_allocator, *src, true, _err);
|
|
|
+ bimg::imageFree(src);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ dst = bimg::imageCubemapFromStripRgba32F(_allocator, *src, _err);
|
|
|
+ bimg::imageFree(src);
|
|
|
+ }
|
|
|
|
|
|
if (!_err->isOk() )
|
|
|
{
|
|
@@ -278,6 +346,27 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
|
|
|
bimg::imageFree(dst);
|
|
|
}
|
|
|
|
|
|
+ if (bimg::LightingModel::Count != _options.radiance)
|
|
|
+ {
|
|
|
+ output = bimg::imageCubemapRadianceFilter(_allocator, *input, _options.radiance, _err);
|
|
|
+
|
|
|
+ if (!_err->isOk() )
|
|
|
+ {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (bimg::TextureFormat::RGBA32F != outputFormat)
|
|
|
+ {
|
|
|
+ bimg::ImageContainer* temp = bimg::imageEncode(_allocator, outputFormat, _options.quality, *output);
|
|
|
+ bimg::imageFree(output);
|
|
|
+
|
|
|
+ output = temp;
|
|
|
+ }
|
|
|
+
|
|
|
+ bimg::imageFree(input);
|
|
|
+ return output;
|
|
|
+ }
|
|
|
+
|
|
|
output = bimg::imageAlloc(
|
|
|
_allocator
|
|
|
, outputFormat
|
|
@@ -531,10 +620,10 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
|
|
|
, bimg::TextureFormat::R8
|
|
|
);
|
|
|
temp = BX_ALLOC(_allocator, size);
|
|
|
- uint8_t* rgba = (uint8_t*)temp;
|
|
|
+ uint8_t* r8 = (uint8_t*)temp;
|
|
|
|
|
|
bimg::imageDecodeToR8(_allocator
|
|
|
- , rgba
|
|
|
+ , r8
|
|
|
, mip.m_data
|
|
|
, mip.m_width
|
|
|
, mip.m_height
|
|
@@ -551,9 +640,85 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
|
|
|
, mip.m_width
|
|
|
, mip.m_height
|
|
|
, mip.m_width
|
|
|
- , _options.edge
|
|
|
- , rgba
|
|
|
+ , r8
|
|
|
);
|
|
|
+
|
|
|
+ if (_options.mips) {
|
|
|
+ const float alphaRef = 0.5f;
|
|
|
+ float coverage = bimg::imageAlphaTestCoverage(bimg::TextureFormat::A8
|
|
|
+ , mip.m_width
|
|
|
+ , mip.m_height
|
|
|
+ , mip.m_width
|
|
|
+ , r8
|
|
|
+ , alphaRef
|
|
|
+ );
|
|
|
+
|
|
|
+ size = bimg::imageGetSize(
|
|
|
+ NULL
|
|
|
+ , uint16_t(dstMip.m_width)
|
|
|
+ , uint16_t(dstMip.m_height)
|
|
|
+ , uint16_t(dstMip.m_depth)
|
|
|
+ , false
|
|
|
+ , false
|
|
|
+ , 1
|
|
|
+ , bimg::TextureFormat::RGBA8
|
|
|
+ );
|
|
|
+ void* rgbaTemp = BX_ALLOC(_allocator, size);
|
|
|
+ uint8_t* rgba = (uint8_t*)rgbaTemp;
|
|
|
+
|
|
|
+ bimg::imageDecodeToRgba8(
|
|
|
+ _allocator
|
|
|
+ , rgba
|
|
|
+ , dstMip.m_data
|
|
|
+ , dstMip.m_width
|
|
|
+ , dstMip.m_height
|
|
|
+ , dstMip.m_width * 4
|
|
|
+ , bimg::TextureFormat::A8
|
|
|
+ );
|
|
|
+
|
|
|
+ for (uint8_t lod = 1; lod < numMips && _err->isOk(); ++lod) {
|
|
|
+ bimg::imageRgba8Downsample2x2(rgba
|
|
|
+ , dstMip.m_width
|
|
|
+ , dstMip.m_height
|
|
|
+ , dstMip.m_depth
|
|
|
+ , dstMip.m_width * 4
|
|
|
+ , bx::strideAlign(dstMip.m_width / 2, blockWidth) * 4
|
|
|
+ , rgba
|
|
|
+ );
|
|
|
+
|
|
|
+ // For each mip, upscale to original size,
|
|
|
+ // scale image alpha to get same coverage as mip0
|
|
|
+ uint32_t upsample = 1 << lod;
|
|
|
+ uint32_t destWidth = dstMip.m_width / 2;
|
|
|
+ uint32_t destHeight = dstMip.m_height / 2;
|
|
|
+ bimg::imageScaleAlphaToCoverage(bimg::TextureFormat::RGBA8
|
|
|
+ , destWidth
|
|
|
+ , destHeight
|
|
|
+ , destWidth * 4
|
|
|
+ , rgba
|
|
|
+ , coverage
|
|
|
+ , alphaRef
|
|
|
+ , upsample
|
|
|
+ );
|
|
|
+
|
|
|
+ bimg::imageGetRawData(*output, side, lod, output->m_data, output->m_size, dstMip);
|
|
|
+ dstData = const_cast<uint8_t*>(dstMip.m_data);
|
|
|
+
|
|
|
+ bimg::imageEncodeFromRgba8(
|
|
|
+ _allocator
|
|
|
+ , dstData
|
|
|
+ , rgba
|
|
|
+ , dstMip.m_width
|
|
|
+ , dstMip.m_height
|
|
|
+ , dstMip.m_depth
|
|
|
+ , bimg::TextureFormat::A8
|
|
|
+ , _options.quality
|
|
|
+ , _err
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ BX_FREE(_allocator, rgbaTemp);
|
|
|
+ }
|
|
|
}
|
|
|
// RGBA8
|
|
|
else
|
|
@@ -749,7 +914,7 @@ void help(const char* _error = NULL, bool _showHelp = true)
|
|
|
" *.exr (input, output) OpenEXR.\n"
|
|
|
" *.gif (input) Graphics Interchange Format.\n"
|
|
|
" *.jpg (input) JPEG Interchange Format.\n"
|
|
|
- " *.hdr (input) Radiance RGBE.\n"
|
|
|
+ " *.hdr (input, output) Radiance RGBE.\n"
|
|
|
" *.ktx (input, output) Khronos Texture.\n"
|
|
|
" *.png (input, output) Portable Network Graphics.\n"
|
|
|
" *.psd (input) Photoshop Document.\n"
|
|
@@ -765,19 +930,24 @@ void help(const char* _error = NULL, bool _showHelp = true)
|
|
|
" -t <format> Output format type (BC1/2/3/4/5, ETC1, PVR14, etc.).\n"
|
|
|
" -q <quality> Encoding quality (default, fastest, highest).\n"
|
|
|
" -m, --mips Generate mip-maps.\n"
|
|
|
+ " --mipskip <N> Skip <N> number of mips.\n"
|
|
|
" -n, --normalmap Input texture is normal map.\n"
|
|
|
- " --equirect Input texture equirectangular projection of cubemap.\n"
|
|
|
- " --sdf <edge> Compute SDF texture.\n"
|
|
|
+ " --equirect Input texture is equirectangular projection of cubemap.\n"
|
|
|
+ " --strip Input texture is horizontal strip of cubemap.\n"
|
|
|
+ " --sdf Compute SDF texture.\n"
|
|
|
" --ref <alpha> Alpha reference value.\n"
|
|
|
" --iqa Image Quality Assessment\n"
|
|
|
" --pma Premultiply alpha into RGB channel.\n"
|
|
|
+ " --linear Input and output texture is linear color space (gamma correction won't be applied).\n"
|
|
|
" --max <max size> Maximum width/height (image will be scaled down and\n"
|
|
|
" aspect ratio will be preserved.\n"
|
|
|
+ " --radiance <model> Radiance cubemap filter. (Lighting model: Phong, PhongBrdf, Blinn, BlinnBrdf, GGX)\n"
|
|
|
" --as <extension> Save as.\n"
|
|
|
+ " --formats List all supported formats.\n"
|
|
|
" --validate *DEBUG* Validate that output image produced matches after loading.\n"
|
|
|
|
|
|
"\n"
|
|
|
- "For additional information, see https://github.com/bkaradzic/bgfx\n"
|
|
|
+ "For additional information, see https://github.com/bkaradzic/bimg\n"
|
|
|
);
|
|
|
}
|
|
|
|
|
@@ -841,6 +1011,24 @@ int main(int _argc, const char* _argv[])
|
|
|
return bx::kExitFailure;
|
|
|
}
|
|
|
|
|
|
+ if (cmdLine.hasArg("formats"))
|
|
|
+ {
|
|
|
+ printf("Uncompressed formats:\n");
|
|
|
+
|
|
|
+ for (int format = bimg::TextureFormat::Unknown + 1; format < bimg::TextureFormat::UnknownDepth; format++)
|
|
|
+ printf(" %s\n", bimg::getName((bimg::TextureFormat::Enum) format));
|
|
|
+
|
|
|
+ for (int format = bimg::TextureFormat::UnknownDepth + 1; format < bimg::TextureFormat::Count; format++)
|
|
|
+ printf(" %s\n", bimg::getName((bimg::TextureFormat::Enum) format));
|
|
|
+
|
|
|
+ printf("Compressed formats:\n");
|
|
|
+
|
|
|
+ for (int format = 0; format < bimg::TextureFormat::Unknown; format++)
|
|
|
+ printf(" %s\n", bimg::getName((bimg::TextureFormat::Enum) format));
|
|
|
+
|
|
|
+ return bx::kExitSuccess;
|
|
|
+ }
|
|
|
+
|
|
|
const char* inputFileName = cmdLine.findOption('f');
|
|
|
if (NULL == inputFileName)
|
|
|
{
|
|
@@ -855,12 +1043,13 @@ int main(int _argc, const char* _argv[])
|
|
|
return bx::kExitFailure;
|
|
|
}
|
|
|
|
|
|
- const char* saveAs = cmdLine.findOption("as");
|
|
|
- saveAs = NULL == saveAs ? bx::strFindI(outputFileName, ".ktx") : saveAs;
|
|
|
- saveAs = NULL == saveAs ? bx::strFindI(outputFileName, ".dds") : saveAs;
|
|
|
- saveAs = NULL == saveAs ? bx::strFindI(outputFileName, ".png") : saveAs;
|
|
|
- saveAs = NULL == saveAs ? bx::strFindI(outputFileName, ".exr") : saveAs;
|
|
|
- if (NULL == saveAs)
|
|
|
+ bx::StringView saveAs = cmdLine.findOption("as");
|
|
|
+ saveAs = saveAs.isEmpty() ? bx::strFindI(outputFileName, ".ktx") : saveAs;
|
|
|
+ saveAs = saveAs.isEmpty() ? bx::strFindI(outputFileName, ".dds") : saveAs;
|
|
|
+ saveAs = saveAs.isEmpty() ? bx::strFindI(outputFileName, ".png") : saveAs;
|
|
|
+ saveAs = saveAs.isEmpty() ? bx::strFindI(outputFileName, ".exr") : saveAs;
|
|
|
+ saveAs = saveAs.isEmpty() ? bx::strFindI(outputFileName, ".hdr") : saveAs;
|
|
|
+ if (saveAs.isEmpty() )
|
|
|
{
|
|
|
help("Output file format must be specified.");
|
|
|
return bx::kExitFailure;
|
|
@@ -868,38 +1057,50 @@ int main(int _argc, const char* _argv[])
|
|
|
|
|
|
Options options;
|
|
|
|
|
|
- const char* edgeOpt = cmdLine.findOption("sdf");
|
|
|
- if (NULL != edgeOpt)
|
|
|
+ const char* alphaRef = cmdLine.findOption("ref");
|
|
|
+ if (NULL != alphaRef)
|
|
|
{
|
|
|
- options.sdf = true;
|
|
|
- if (!bx::fromString(&options.edge, edgeOpt) )
|
|
|
+ options.alphaTest = true;
|
|
|
+ if (!bx::fromString(&options.edge, alphaRef))
|
|
|
{
|
|
|
- options.edge = 255.0f;
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- const char* alphaRef = cmdLine.findOption("ref");
|
|
|
- if (NULL != alphaRef)
|
|
|
- {
|
|
|
- options.alphaTest = true;
|
|
|
- if (!bx::fromString(&options.edge, alphaRef))
|
|
|
- {
|
|
|
- options.edge = 0.5f;
|
|
|
- }
|
|
|
+ options.edge = 0.5f;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- options.mips = cmdLine.hasArg('m', "mips");
|
|
|
- options.normalMap = cmdLine.hasArg('n', "normalmap");
|
|
|
+ options.sdf = cmdLine.hasArg("sdf");
|
|
|
+ options.mips = cmdLine.hasArg('m', "mips");
|
|
|
+ options.normalMap = cmdLine.hasArg('n', "normalmap");
|
|
|
options.equirect = cmdLine.hasArg("equirect");
|
|
|
+ options.strip = cmdLine.hasArg("strip");
|
|
|
options.iqa = cmdLine.hasArg("iqa");
|
|
|
options.pma = cmdLine.hasArg("pma");
|
|
|
+ options.linear = cmdLine.hasArg("linear");
|
|
|
+
|
|
|
+ if (options.equirect
|
|
|
+ && options.strip)
|
|
|
+ {
|
|
|
+ help("Image can't be equirect and strip at the same time.");
|
|
|
+ return bx::kExitFailure;
|
|
|
+ }
|
|
|
|
|
|
const char* maxSize = cmdLine.findOption("max");
|
|
|
if (NULL != maxSize)
|
|
|
{
|
|
|
- options.maxSize = atoi(maxSize);
|
|
|
+ if (!bx::fromString(&options.maxSize, maxSize) )
|
|
|
+ {
|
|
|
+ help("Parsing `--max` failed.");
|
|
|
+ return bx::kExitFailure;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const char* mipSkip = cmdLine.findOption("mipskip");
|
|
|
+ if (NULL != mipSkip)
|
|
|
+ {
|
|
|
+ if (!bx::fromString(&options.mipSkip, mipSkip) )
|
|
|
+ {
|
|
|
+ help("Parsing `--mipskip` failed.");
|
|
|
+ return bx::kExitFailure;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
options.format = bimg::TextureFormat::Count;
|
|
@@ -915,7 +1116,7 @@ int main(int _argc, const char* _argv[])
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (NULL != bx::strFindI(saveAs, "png") )
|
|
|
+ if (!bx::strFindI(saveAs, "png").isEmpty() )
|
|
|
{
|
|
|
if (options.format == bimg::TextureFormat::Count)
|
|
|
{
|
|
@@ -927,7 +1128,7 @@ int main(int _argc, const char* _argv[])
|
|
|
return bx::kExitFailure;
|
|
|
}
|
|
|
}
|
|
|
- else if (NULL != bx::strFindI(saveAs, "exr") )
|
|
|
+ else if (!bx::strFindI(saveAs, "exr").isEmpty() )
|
|
|
{
|
|
|
if (options.format == bimg::TextureFormat::Count)
|
|
|
{
|
|
@@ -954,6 +1155,21 @@ int main(int _argc, const char* _argv[])
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ const char* radiance = cmdLine.findOption("radiance");
|
|
|
+ if (NULL != radiance)
|
|
|
+ {
|
|
|
+ if (0 == bx::strCmpI(radiance, "phong" ) ) { options.radiance = bimg::LightingModel::Phong; }
|
|
|
+ else if (0 == bx::strCmpI(radiance, "phongbrdf") ) { options.radiance = bimg::LightingModel::PhongBrdf; }
|
|
|
+ else if (0 == bx::strCmpI(radiance, "blinn" ) ) { options.radiance = bimg::LightingModel::Blinn; }
|
|
|
+ else if (0 == bx::strCmpI(radiance, "blinnbrdf") ) { options.radiance = bimg::LightingModel::BlinnBrdf; }
|
|
|
+ else if (0 == bx::strCmpI(radiance, "ggx" ) ) { options.radiance = bimg::LightingModel::Ggx; }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ help("Invalid radiance lighting model specified.");
|
|
|
+ return bx::kExitFailure;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
const bool validate = cmdLine.hasArg("validate");
|
|
|
|
|
|
bx::Error err;
|
|
@@ -994,15 +1210,15 @@ int main(int _argc, const char* _argv[])
|
|
|
bx::FileWriter writer;
|
|
|
if (bx::open(&writer, outputFileName, false, &err) )
|
|
|
{
|
|
|
- if (NULL != bx::strFindI(saveAs, "ktx") )
|
|
|
+ if (!bx::strFindI(saveAs, "ktx").isEmpty() )
|
|
|
{
|
|
|
bimg::imageWriteKtx(&writer, *output, output->m_data, output->m_size, &err);
|
|
|
}
|
|
|
- else if (NULL != bx::strFindI(saveAs, "dds") )
|
|
|
+ else if (!bx::strFindI(saveAs, "dds").isEmpty() )
|
|
|
{
|
|
|
bimg::imageWriteDds(&writer, *output, output->m_data, output->m_size, &err);
|
|
|
}
|
|
|
- else if (NULL != bx::strFindI(saveAs, "png") )
|
|
|
+ else if (!bx::strFindI(saveAs, "png").isEmpty() )
|
|
|
{
|
|
|
if (output->m_format != bimg::TextureFormat::RGBA8)
|
|
|
{
|
|
@@ -1019,9 +1235,10 @@ int main(int _argc, const char* _argv[])
|
|
|
, mip.m_data
|
|
|
, output->m_format
|
|
|
, false
|
|
|
- , &err);
|
|
|
+ , &err
|
|
|
+ );
|
|
|
}
|
|
|
- else if (NULL != bx::strFindI(saveAs, "exr") )
|
|
|
+ else if (!bx::strFindI(saveAs, "exr").isEmpty() )
|
|
|
{
|
|
|
bimg::ImageMip mip;
|
|
|
bimg::imageGetRawData(*output, 0, 0, output->m_data, output->m_size, mip);
|
|
@@ -1032,7 +1249,22 @@ int main(int _argc, const char* _argv[])
|
|
|
, mip.m_data
|
|
|
, output->m_format
|
|
|
, false
|
|
|
- , &err);
|
|
|
+ , &err
|
|
|
+ );
|
|
|
+ }
|
|
|
+ else if (!bx::strFindI(saveAs, "hdr").isEmpty() )
|
|
|
+ {
|
|
|
+ bimg::ImageMip mip;
|
|
|
+ bimg::imageGetRawData(*output, 0, 0, output->m_data, output->m_size, mip);
|
|
|
+ bimg::imageWriteHdr(&writer
|
|
|
+ , mip.m_width
|
|
|
+ , mip.m_height
|
|
|
+ , mip.m_width*getBitsPerPixel(mip.m_format)/8
|
|
|
+ , mip.m_data
|
|
|
+ , output->m_format
|
|
|
+ , false
|
|
|
+ , &err
|
|
|
+ );
|
|
|
}
|
|
|
|
|
|
bx::close(&writer);
|