mirror of
https://github.com/bkaradzic/bimg.git
synced 2026-02-21 14:23:03 +01:00
6
3rdparty/nvtt/nvtt.cpp
vendored
6
3rdparty/nvtt/nvtt.cpp
vendored
@@ -50,9 +50,9 @@ namespace nvtt
|
||||
for (uint32_t blockX = 0; blockX < ZOH::Tile::TILE_W; ++blockX)
|
||||
{
|
||||
nv::Vector4 color = srcRgba[blockY*srcRgbaStride + blockX];
|
||||
zohTile.data[blockY][blockX].x = float(int16_t(bx::halfFromFloat(color.x) ) );
|
||||
zohTile.data[blockY][blockX].y = float(int16_t(bx::halfFromFloat(color.y) ) );
|
||||
zohTile.data[blockY][blockX].z = float(int16_t(bx::halfFromFloat(color.z) ) );
|
||||
zohTile.data[blockY][blockX].x = float(int16_t(bx::halfFromFloat(bx::max(color.x, 0.0f) ) ) );
|
||||
zohTile.data[blockY][blockX].y = float(int16_t(bx::halfFromFloat(bx::max(color.y, 0.0f) ) ) );
|
||||
zohTile.data[blockY][blockX].z = float(int16_t(bx::halfFromFloat(bx::max(color.z, 0.0f) ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
585
3rdparty/tinyexr/tinyexr.h
vendored
585
3rdparty/tinyexr/tinyexr.h
vendored
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,7 @@
|
||||
#include <stdint.h> // uint32_t
|
||||
#include <stdlib.h> // NULL
|
||||
|
||||
#define BIMG_API_VERSION UINT32_C(6)
|
||||
#define BIMG_API_VERSION UINT32_C(7)
|
||||
|
||||
namespace bx
|
||||
{
|
||||
@@ -73,7 +73,7 @@ namespace bimg
|
||||
ASTC6x6, //!< ASTC 6x6 3.56 BPP
|
||||
ASTC8x5, //!< ASTC 8x5 3.20 BPP
|
||||
ASTC8x6, //!< ASTC 8x6 2.67 BPP
|
||||
ASTC10x5, //!< ASTC 10x5 2.56 BPP
|
||||
ASTC10x5, //!< ASTC 10x5 2.56 BPP
|
||||
|
||||
Unknown, // Compressed formats above.
|
||||
|
||||
@@ -334,6 +334,16 @@ namespace bimg
|
||||
, const void* _src
|
||||
);
|
||||
|
||||
///
|
||||
void imageRgba32fDownsample2x2(
|
||||
void* _dst
|
||||
, uint32_t _width
|
||||
, uint32_t _height
|
||||
, uint32_t _depth
|
||||
, uint32_t _srcPitch
|
||||
, const void* _src
|
||||
);
|
||||
|
||||
///
|
||||
void imageRgba32fDownsample2x2NormalMap(
|
||||
void* _dst
|
||||
@@ -493,6 +503,18 @@ namespace bimg
|
||||
, bx::Error* _err
|
||||
);
|
||||
|
||||
///
|
||||
int32_t imageWriteHdr(
|
||||
bx::WriterI* _writer
|
||||
, uint32_t _width
|
||||
, uint32_t _height
|
||||
, uint32_t _srcPitch
|
||||
, const void* _src
|
||||
, TextureFormat::Enum _format
|
||||
, bool _yflip
|
||||
, bx::Error* _err
|
||||
);
|
||||
|
||||
///
|
||||
int32_t imageWriteDds(
|
||||
bx::WriterI* _writer
|
||||
@@ -628,14 +650,6 @@ namespace bimg
|
||||
, ImageMip& _mip
|
||||
);
|
||||
|
||||
///
|
||||
ImageContainer* imageCubemapFromLatLongRgba32F(
|
||||
bx::AllocatorI* _allocator
|
||||
, const ImageContainer& _input
|
||||
, bool _useBilinearInterpolation
|
||||
, bx::Error* _err
|
||||
);
|
||||
|
||||
} // namespace bimg
|
||||
|
||||
#endif // BIMG_IMAGE_H_HEADER_GUARD
|
||||
|
||||
@@ -127,6 +127,49 @@ namespace bimg
|
||||
, float _alphaRef
|
||||
);
|
||||
|
||||
///
|
||||
ImageContainer* imageCubemapFromLatLongRgba32F(
|
||||
bx::AllocatorI* _allocator
|
||||
, const ImageContainer& _input
|
||||
, bool _useBilinearInterpolation
|
||||
, bx::Error* _err
|
||||
);
|
||||
|
||||
///
|
||||
ImageContainer* imageCubemapFromStripRgba32F(
|
||||
bx::AllocatorI* _allocator
|
||||
, const ImageContainer& _input
|
||||
, bx::Error* _err
|
||||
);
|
||||
|
||||
///
|
||||
ImageContainer* imageGenerateMips(
|
||||
bx::AllocatorI* _allocator
|
||||
, const ImageContainer& _image
|
||||
);
|
||||
|
||||
struct LightingModel
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Phong,
|
||||
PhongBrdf,
|
||||
Blinn,
|
||||
BlinnBrdf,
|
||||
Ggx,
|
||||
|
||||
Count
|
||||
};
|
||||
};
|
||||
|
||||
///
|
||||
ImageContainer* imageCubemapRadianceFilter(
|
||||
bx::AllocatorI* _allocator
|
||||
, const ImageContainer& _image
|
||||
, LightingModel::Enum _lightingModel
|
||||
, bx::Error* _err
|
||||
);
|
||||
|
||||
} // namespace bimg
|
||||
|
||||
#endif // BIMG_ENCODE_H_HEADER_GUARD
|
||||
|
||||
2
makefile
2
makefile
@@ -308,7 +308,7 @@ texturev: .build/projects/$(BUILD_PROJECT_DIR) ## Build texturev tool.
|
||||
$(SILENT) $(MAKE) -C .build/projects/$(BUILD_PROJECT_DIR) texturev config=$(BUILD_TOOLS_CONFIG)
|
||||
$(SILENT) cp .build/$(BUILD_OUTPUT_DIR)/bin/texturev$(BUILD_TOOLS_SUFFIX)$(EXE) tools/bin/$(OS)/texturev$(EXE)
|
||||
|
||||
tools: geometryc shaderc texturec texturev ## Build tools.
|
||||
tools: texturec ## Build tools.
|
||||
|
||||
clean-tools: ## Clean tools projects.
|
||||
-$(SILENT) rm -r .build/projects/$(BUILD_PROJECT_DIR)
|
||||
|
||||
@@ -17,6 +17,7 @@ project "bimg_encode"
|
||||
files {
|
||||
path.join(BIMG_DIR, "include/**"),
|
||||
path.join(BIMG_DIR, "src/image_encode.*"),
|
||||
path.join(BIMG_DIR, "src/image_cubemap_filter.*"),
|
||||
path.join(BIMG_DIR, "3rdparty/libsquish/**.cpp"),
|
||||
path.join(BIMG_DIR, "3rdparty/libsquish/**.h"),
|
||||
path.join(BIMG_DIR, "3rdparty/edtaa3/**.cpp"),
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace bimg
|
||||
{
|
||||
if (_hasMips)
|
||||
{
|
||||
const uint32_t max = bx::uint32_max(bx::uint32_max(_width, _height), _depth);
|
||||
const uint32_t max = bx::max(_width, _height, _depth);
|
||||
const uint32_t num = 1 + uint32_t(bx::log2(float(max) ) );
|
||||
|
||||
return uint8_t(num);
|
||||
|
||||
663
src/image.cpp
663
src/image.cpp
@@ -10,7 +10,7 @@ namespace bimg
|
||||
{
|
||||
static const ImageBlockInfo s_imageBlockInfo[] =
|
||||
{
|
||||
// +-------------------------------------------- bits per pixel
|
||||
// +--------------------------------------------- bits per pixel
|
||||
// | +----------------------------------------- block width
|
||||
// | | +-------------------------------------- block height
|
||||
// | | | +---------------------------------- block size
|
||||
@@ -38,15 +38,15 @@ namespace bimg
|
||||
{ 4, 4, 4, 8, 2, 2, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // PTC14A
|
||||
{ 2, 8, 4, 8, 2, 2, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // PTC22
|
||||
{ 4, 4, 4, 8, 2, 2, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // PTC24
|
||||
{ 4, 4, 4, 8, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ATC
|
||||
{ 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ATCE
|
||||
{ 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ATCI
|
||||
{ 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ASTC4x4
|
||||
{ 6, 5, 5, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ASTC5x5
|
||||
{ 4, 6, 6, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ASTC6x6
|
||||
{ 4, 8, 5, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ASTC8x5
|
||||
{ 3, 8, 6, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ASTC8x6
|
||||
{ 3, 10, 5, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ASTC10x5
|
||||
{ 4, 4, 4, 8, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ATC
|
||||
{ 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ATCE
|
||||
{ 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ATCI
|
||||
{ 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ASTC4x4
|
||||
{ 6, 5, 5, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ASTC5x5
|
||||
{ 4, 6, 6, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ASTC6x6
|
||||
{ 4, 8, 5, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ASTC8x5
|
||||
{ 3, 8, 6, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ASTC8x6
|
||||
{ 3, 10, 5, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ASTC10x5
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Count) }, // Unknown
|
||||
{ 1, 8, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // R1
|
||||
{ 8, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 8, uint8_t(bx::EncodingType::Unorm) }, // A8
|
||||
@@ -128,15 +128,15 @@ namespace bimg
|
||||
"PTC14A", // PTC14A
|
||||
"PTC22", // PTC22
|
||||
"PTC24", // PTC24
|
||||
"ATC", // ATC
|
||||
"ATCE", // ATCE
|
||||
"ATCI", // ATCI
|
||||
"ASTC4x4", // ASTC4x4
|
||||
"ASTC5x5", // ASTC5x5
|
||||
"ASTC6x6", // ASTC6x6
|
||||
"ASTC8x5", // ASTC8x5
|
||||
"ASTC8x6", // ASTC8x6
|
||||
"ASTC10x5", // ASTC10x5
|
||||
"ATC", // ATC
|
||||
"ATCE", // ATCE
|
||||
"ATCI", // ATCI
|
||||
"ASTC4x4", // ASTC4x4
|
||||
"ASTC5x5", // ASTC5x5
|
||||
"ASTC6x6", // ASTC6x6
|
||||
"ASTC8x5", // ASTC8x5
|
||||
"ASTC8x6", // ASTC8x6
|
||||
"ASTC10x5", // ASTC10x5
|
||||
"<unknown>", // Unknown
|
||||
"R1", // R1
|
||||
"A8", // A8
|
||||
@@ -276,9 +276,9 @@ namespace bimg
|
||||
const uint16_t minBlockX = blockInfo.minBlockX;
|
||||
const uint16_t minBlockY = blockInfo.minBlockY;
|
||||
|
||||
_width = bx::uint16_max(blockWidth * minBlockX, ( (_width + blockWidth - 1) / blockWidth )*blockWidth);
|
||||
_height = bx::uint16_max(blockHeight * minBlockY, ( (_height + blockHeight - 1) / blockHeight)*blockHeight);
|
||||
_depth = bx::uint16_max(1, _depth);
|
||||
_width = bx::max<uint16_t>(blockWidth * minBlockX, ( (_width + blockWidth - 1) / blockWidth )*blockWidth);
|
||||
_height = bx::max<uint16_t>(blockHeight * minBlockY, ( (_height + blockHeight - 1) / blockHeight)*blockHeight);
|
||||
_depth = bx::max<uint16_t>(1, _depth);
|
||||
|
||||
uint8_t numMips = calcNumMips(true, _width, _height, _depth);
|
||||
|
||||
@@ -289,12 +289,15 @@ namespace bimg
|
||||
{
|
||||
const ImageBlockInfo& blockInfo = getBlockInfo(_format);
|
||||
const uint8_t bpp = blockInfo.bitsPerPixel;
|
||||
const uint16_t blockSize = blockInfo.blockSize;
|
||||
const uint16_t blockWidth = blockInfo.blockWidth;
|
||||
const uint16_t blockHeight = blockInfo.blockHeight;
|
||||
const uint16_t minBlockX = blockInfo.minBlockX;
|
||||
const uint16_t minBlockY = blockInfo.minBlockY;
|
||||
const uint8_t blockSize = blockInfo.blockSize;
|
||||
|
||||
_width = bx::max<uint16_t>(blockWidth * minBlockX, ( (_width + blockWidth - 1) / blockWidth)*blockWidth);
|
||||
_height = bx::max<uint16_t>(blockHeight * minBlockY, ( (_height + blockHeight - 1) / blockHeight)*blockHeight);
|
||||
_depth = bx::max<uint16_t>(1, _depth);
|
||||
const uint8_t numMips = calcNumMips(_hasMips, _width, _height, _depth);
|
||||
const uint32_t sides = _cubeMap ? 6 : 1;
|
||||
|
||||
@@ -303,22 +306,18 @@ namespace bimg
|
||||
uint32_t depth = _depth;
|
||||
uint32_t size = 0;
|
||||
|
||||
if (_format != TextureFormat::Unknown)
|
||||
{
|
||||
for (uint32_t lod = 0; lod < numMips; ++lod)
|
||||
{
|
||||
depth = bx::uint32_max(1, depth);
|
||||
for (uint32_t lod = 0; lod < numMips; ++lod)
|
||||
{
|
||||
width = bx::max<uint32_t>(blockWidth * minBlockX, ( (width + blockWidth - 1) / blockWidth )*blockWidth);
|
||||
height = bx::max<uint32_t>(blockHeight * minBlockY, ( (height + blockHeight - 1) / blockHeight)*blockHeight);
|
||||
depth = bx::max<uint32_t>(1, depth);
|
||||
|
||||
uint16_t blocksX = bx::uint32_max(minBlockX, ((width + blockWidth - 1) / blockWidth ));
|
||||
uint16_t blocksY = bx::uint32_max(minBlockY, ((height + blockHeight - 1) / blockHeight));
|
||||
size += uint32_t(uint64_t(width/blockWidth * height/blockHeight * depth)*blockSize * sides);
|
||||
|
||||
size += blocksX * blocksY * blockSize * depth * sides;
|
||||
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
depth >>= 1;
|
||||
}
|
||||
}
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
depth >>= 1;
|
||||
}
|
||||
|
||||
size *= _numLayers;
|
||||
|
||||
@@ -338,7 +337,7 @@ namespace bimg
|
||||
return size;
|
||||
}
|
||||
|
||||
void imageSolid(void* _dst, uint32_t _width, uint32_t _height, uint32_t _solid)
|
||||
void imageSolid(void* _dst, uint32_t _width, uint32_t _height, uint32_t _solid)
|
||||
{
|
||||
uint32_t* dst = (uint32_t*)_dst;
|
||||
for (uint32_t ii = 0, num = _width*_height; ii < num; ++ii)
|
||||
@@ -711,6 +710,136 @@ namespace bimg
|
||||
imageRgba32fLinearDownsample2x2Ref(_dst, _width, _height, _depth, _srcPitch, _src);
|
||||
}
|
||||
|
||||
void imageRgba32fDownsample2x2Ref(void* _dst, uint32_t _width, uint32_t _height, uint32_t _depth, uint32_t _srcPitch, const void* _src)
|
||||
{
|
||||
const uint32_t dstWidth = _width/2;
|
||||
const uint32_t dstHeight = _height/2;
|
||||
const uint32_t dstDepth = _depth/2;
|
||||
|
||||
if (0 == dstWidth
|
||||
|| 0 == dstHeight)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const uint8_t* src = (const uint8_t*)_src;
|
||||
uint8_t* dst = (uint8_t*)_dst;
|
||||
|
||||
if (0 == dstDepth)
|
||||
{
|
||||
for (uint32_t yy = 0, ystep = _srcPitch*2; yy < dstHeight; ++yy, src += ystep)
|
||||
{
|
||||
const float* rgba0 = (const float*)&src[0];
|
||||
const float* rgba1 = (const float*)&src[_srcPitch];
|
||||
for (uint32_t xx = 0; xx < dstWidth; ++xx, rgba0 += 8, rgba1 += 8, dst += 16)
|
||||
{
|
||||
float xyz[4];
|
||||
|
||||
xyz[0] = bx::toLinear(rgba0[0]);
|
||||
xyz[1] = bx::toLinear(rgba0[1]);
|
||||
xyz[2] = bx::toLinear(rgba0[2]);
|
||||
xyz[3] = rgba0[3];
|
||||
|
||||
xyz[0] += bx::toLinear(rgba0[4]);
|
||||
xyz[1] += bx::toLinear(rgba0[5]);
|
||||
xyz[2] += bx::toLinear(rgba0[6]);
|
||||
xyz[3] += rgba0[7];
|
||||
|
||||
xyz[0] += bx::toLinear(rgba1[0]);
|
||||
xyz[1] += bx::toLinear(rgba1[1]);
|
||||
xyz[2] += bx::toLinear(rgba1[2]);
|
||||
xyz[3] += rgba1[3];
|
||||
|
||||
xyz[0] += bx::toLinear(rgba1[4]);
|
||||
xyz[1] += bx::toLinear(rgba1[5]);
|
||||
xyz[2] += bx::toLinear(rgba1[6]);
|
||||
xyz[3] += rgba1[7];
|
||||
|
||||
xyz[0] = bx::toGamma(xyz[0]/4.0f);
|
||||
xyz[1] = bx::toGamma(xyz[1]/4.0f);
|
||||
xyz[2] = bx::toGamma(xyz[2]/4.0f);
|
||||
xyz[3] = xyz[3]/4.0f;
|
||||
|
||||
bx::packRgba32F(dst, xyz);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint32_t slicePitch = _srcPitch*_height;
|
||||
|
||||
for (uint32_t zz = 0; zz < dstDepth; ++zz, src += slicePitch)
|
||||
{
|
||||
for (uint32_t yy = 0, ystep = _srcPitch*2; yy < dstHeight; ++yy, src += ystep)
|
||||
{
|
||||
const float* rgba0 = (const float*)&src[0];
|
||||
const float* rgba1 = (const float*)&src[_srcPitch];
|
||||
const float* rgba2 = (const float*)&src[slicePitch];
|
||||
const float* rgba3 = (const float*)&src[slicePitch+_srcPitch];
|
||||
for (uint32_t xx = 0
|
||||
; xx < dstWidth
|
||||
; ++xx, rgba0 += 8, rgba1 += 8, rgba2 += 8, rgba3 += 8, dst += 16
|
||||
)
|
||||
{
|
||||
float xyz[4];
|
||||
|
||||
xyz[0] = bx::toLinear(rgba0[0]);
|
||||
xyz[1] = bx::toLinear(rgba0[1]);
|
||||
xyz[2] = bx::toLinear(rgba0[2]);
|
||||
xyz[3] = rgba0[3];
|
||||
|
||||
xyz[0] += bx::toLinear(rgba0[4]);
|
||||
xyz[1] += bx::toLinear(rgba0[5]);
|
||||
xyz[2] += bx::toLinear(rgba0[6]);
|
||||
xyz[3] += rgba0[7];
|
||||
|
||||
xyz[0] += bx::toLinear(rgba1[0]);
|
||||
xyz[1] += bx::toLinear(rgba1[1]);
|
||||
xyz[2] += bx::toLinear(rgba1[2]);
|
||||
xyz[3] += rgba1[3];
|
||||
|
||||
xyz[0] += bx::toLinear(rgba1[4]);
|
||||
xyz[1] += bx::toLinear(rgba1[5]);
|
||||
xyz[2] += bx::toLinear(rgba1[6]);
|
||||
xyz[3] += rgba1[7];
|
||||
|
||||
xyz[0] += bx::toLinear(rgba2[0]);
|
||||
xyz[1] += bx::toLinear(rgba2[1]);
|
||||
xyz[2] += bx::toLinear(rgba2[2]);
|
||||
xyz[3] += rgba2[3];
|
||||
|
||||
xyz[0] += bx::toLinear(rgba2[4]);
|
||||
xyz[1] += bx::toLinear(rgba2[5]);
|
||||
xyz[2] += bx::toLinear(rgba2[6]);
|
||||
xyz[3] += rgba2[7];
|
||||
|
||||
xyz[0] += bx::toLinear(rgba3[0]);
|
||||
xyz[1] += bx::toLinear(rgba3[1]);
|
||||
xyz[2] += bx::toLinear(rgba3[2]);
|
||||
xyz[3] += rgba3[3];
|
||||
|
||||
xyz[0] += bx::toLinear(rgba3[4]);
|
||||
xyz[1] += bx::toLinear(rgba3[5]);
|
||||
xyz[2] += bx::toLinear(rgba3[6]);
|
||||
xyz[3] += rgba3[7];
|
||||
|
||||
xyz[0] = bx::toGamma(xyz[0]/8.0f);
|
||||
xyz[1] = bx::toGamma(xyz[1]/8.0f);
|
||||
xyz[2] = bx::toGamma(xyz[2]/8.0f);
|
||||
xyz[3] = xyz[3]/8.0f;
|
||||
|
||||
bx::packRgba32F(dst, xyz);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void imageRgba32fDownsample2x2(void* _dst, uint32_t _width, uint32_t _height, uint32_t _depth, uint32_t _srcPitch, const void* _src)
|
||||
{
|
||||
imageRgba32fDownsample2x2Ref(_dst, _width, _height, _depth, _srcPitch, _src);
|
||||
}
|
||||
|
||||
void imageRgba32fDownsample2x2NormalMapRef(void* _dst, uint32_t _width, uint32_t _height, uint32_t _srcPitch, uint32_t _dstPitch, const void* _src)
|
||||
{
|
||||
const uint32_t dstWidth = _width/2;
|
||||
@@ -872,15 +1001,15 @@ namespace bimg
|
||||
{ NULL, NULL }, // PTC14A
|
||||
{ NULL, NULL }, // PTC22
|
||||
{ NULL, NULL }, // PTC24
|
||||
{ NULL, NULL }, // ATC
|
||||
{ NULL, NULL }, // ATCE
|
||||
{ NULL, NULL }, // ATCI
|
||||
{ NULL, NULL }, // ASTC4x4
|
||||
{ NULL, NULL }, // ASTC5x5
|
||||
{ NULL, NULL }, // ASTC6x6
|
||||
{ NULL, NULL }, // ASTC8x5
|
||||
{ NULL, NULL }, // ASTC8x6
|
||||
{ NULL, NULL }, // ASTC10x5
|
||||
{ NULL, NULL }, // ATC
|
||||
{ NULL, NULL }, // ATCE
|
||||
{ NULL, NULL }, // ATCI
|
||||
{ NULL, NULL }, // ASTC4x4
|
||||
{ NULL, NULL }, // ASTC5x5
|
||||
{ NULL, NULL }, // ASTC6x6
|
||||
{ NULL, NULL }, // ASTC8x5
|
||||
{ NULL, NULL }, // ASTC8x6
|
||||
{ NULL, NULL }, // ASTC10x5
|
||||
{ NULL, NULL }, // Unknown
|
||||
{ NULL, NULL }, // R1
|
||||
{ bx::packR8, bx::unpackR8 }, // A8
|
||||
@@ -1039,7 +1168,7 @@ namespace bimg
|
||||
|
||||
if (_dstFormat == _srcFormat)
|
||||
{
|
||||
bx::memCopy(_dst, _src, _width*_height*_depth*srcBpp/8);
|
||||
bx::memCopy(_dst, _src, _width*_height*_depth*(srcBpp/8) );
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2267,61 +2396,61 @@ namespace bimg
|
||||
}
|
||||
}
|
||||
|
||||
// BC6H, BC7
|
||||
// ATC
|
||||
//
|
||||
void decodeBlockATC(uint8_t _dst[16*4], const uint8_t _src[8])
|
||||
{
|
||||
uint8_t colors[4*4]; // You can see from comparison with decodeBlockDXT just how little sense the ATI patent-avoiding(?) modification makes
|
||||
void decodeBlockATC(uint8_t _dst[16*4], const uint8_t _src[8])
|
||||
{
|
||||
uint8_t colors[4*4];
|
||||
|
||||
uint32_t c0 = _src[0] | (_src[1] << 8);
|
||||
uint32_t c1 = _src[2] | (_src[3] << 8);
|
||||
uint32_t c0 = _src[0] | (_src[1] << 8);
|
||||
uint32_t c1 = _src[2] | (_src[3] << 8);
|
||||
|
||||
if ((c0 & 0x8000) == 0)
|
||||
{
|
||||
colors[0] = bitRangeConvert( (c0>> 0)&0x1f, 5, 8);
|
||||
colors[1] = bitRangeConvert( (c0>> 5)&0x1f, 5, 8);
|
||||
colors[2] = bitRangeConvert( (c0>>10)&0x1f, 5, 8);
|
||||
if (0 == (c0 & 0x8000) )
|
||||
{
|
||||
colors[ 0] = bitRangeConvert( (c0>> 0)&0x1f, 5, 8);
|
||||
colors[ 1] = bitRangeConvert( (c0>> 5)&0x1f, 5, 8);
|
||||
colors[ 2] = bitRangeConvert( (c0>>10)&0x1f, 5, 8);
|
||||
|
||||
colors[12] = bitRangeConvert( (c1>> 0)&0x1f, 5, 8);
|
||||
colors[13] = bitRangeConvert( (c1>> 5)&0x3f, 6, 8);
|
||||
colors[14] = bitRangeConvert( (c1>>11)&0x1f, 5, 8);
|
||||
colors[12] = bitRangeConvert( (c1>> 0)&0x1f, 5, 8);
|
||||
colors[13] = bitRangeConvert( (c1>> 5)&0x3f, 6, 8);
|
||||
colors[14] = bitRangeConvert( (c1>>11)&0x1f, 5, 8);
|
||||
|
||||
colors[ 4] = (2 * colors[0] + colors[12]) / 3;
|
||||
colors[ 5] = (2 * colors[1] + colors[13]) / 3;
|
||||
colors[ 6] = (2 * colors[2] + colors[14]) / 3;
|
||||
colors[ 4] = (2 * colors[0] + colors[12]) / 3;
|
||||
colors[ 5] = (2 * colors[1] + colors[13]) / 3;
|
||||
colors[ 6] = (2 * colors[2] + colors[14]) / 3;
|
||||
|
||||
colors[ 8] = (colors[0] + 2 * colors[12]) / 3;
|
||||
colors[ 9] = (colors[1] + 2 * colors[13]) / 3;
|
||||
colors[10] = (colors[2] + 2 * colors[14]) / 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
colors[ 0] = 0;
|
||||
colors[ 1] = 0;
|
||||
colors[ 2] = 0;
|
||||
colors[ 8] = (colors[0] + 2 * colors[12]) / 3;
|
||||
colors[ 9] = (colors[1] + 2 * colors[13]) / 3;
|
||||
colors[10] = (colors[2] + 2 * colors[14]) / 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
colors[ 0] = 0;
|
||||
colors[ 1] = 0;
|
||||
colors[ 2] = 0;
|
||||
|
||||
colors[ 8] = bitRangeConvert( (c0>> 0)&0x1f, 5, 8);
|
||||
colors[ 9] = bitRangeConvert( (c0>> 5)&0x1f, 5, 8);
|
||||
colors[10] = bitRangeConvert( (c0>>10)&0x1f, 5, 8);
|
||||
colors[ 8] = bitRangeConvert( (c0>> 0)&0x1f, 5, 8);
|
||||
colors[ 9] = bitRangeConvert( (c0>> 5)&0x1f, 5, 8);
|
||||
colors[10] = bitRangeConvert( (c0>>10)&0x1f, 5, 8);
|
||||
|
||||
colors[12] = bitRangeConvert( (c1>> 0)&0x1f, 5, 8);
|
||||
colors[13] = bitRangeConvert( (c1>> 5)&0x3f, 6, 8);
|
||||
colors[14] = bitRangeConvert( (c1>>11)&0x1f, 5, 8);
|
||||
colors[12] = bitRangeConvert( (c1>> 0)&0x1f, 5, 8);
|
||||
colors[13] = bitRangeConvert( (c1>> 5)&0x3f, 6, 8);
|
||||
colors[14] = bitRangeConvert( (c1>>11)&0x1f, 5, 8);
|
||||
|
||||
colors[ 4] = colors[ 8] - colors[12] / 4;
|
||||
colors[ 5] = colors[ 9] - colors[13] / 4;
|
||||
colors[ 6] = colors[10] - colors[14] / 4;
|
||||
}
|
||||
colors[ 4] = colors[ 8] - colors[12] / 4;
|
||||
colors[ 5] = colors[ 9] - colors[13] / 4;
|
||||
colors[ 6] = colors[10] - colors[14] / 4;
|
||||
}
|
||||
|
||||
for (uint32_t ii = 0, next = 8*4; ii < 16*4; ii += 4, next += 2)
|
||||
{
|
||||
int idx = ( (_src[next>>3] >> (next & 7) ) & 3) * 4;
|
||||
_dst[ii+0] = colors[idx+0];
|
||||
_dst[ii+1] = colors[idx+1];
|
||||
_dst[ii+2] = colors[idx+2];
|
||||
_dst[ii+3] = colors[idx+3];
|
||||
}
|
||||
}
|
||||
for (uint32_t ii = 0, next = 8*4; ii < 16*4; ii += 4, next += 2)
|
||||
{
|
||||
int32_t idx = ( (_src[next>>3] >> (next & 7) ) & 3) * 4;
|
||||
_dst[ii+0] = colors[idx+0];
|
||||
_dst[ii+1] = colors[idx+1];
|
||||
_dst[ii+2] = colors[idx+2];
|
||||
_dst[ii+3] = colors[idx+3];
|
||||
}
|
||||
}
|
||||
|
||||
static const int32_t s_etc1Mod[8][4] =
|
||||
{
|
||||
@@ -2968,10 +3097,10 @@ namespace bimg
|
||||
const uint16_t minBlockX = blockInfo.minBlockX;
|
||||
const uint16_t minBlockY = blockInfo.minBlockY;
|
||||
|
||||
_width = bx::uint16_max(blockWidth * minBlockX, ( (_width + blockWidth - 1) / blockWidth)*blockWidth);
|
||||
_height = bx::uint16_max(blockHeight * minBlockY, ( (_height + blockHeight - 1) / blockHeight)*blockHeight);
|
||||
_depth = bx::uint16_max(1, _depth);
|
||||
_numLayers = bx::uint16_max(1, _numLayers);
|
||||
_width = bx::max<uint16_t>(blockWidth * minBlockX, ( (_width + blockWidth - 1) / blockWidth)*blockWidth);
|
||||
_height = bx::max<uint16_t>(blockHeight * minBlockY, ( (_height + blockHeight - 1) / blockHeight)*blockHeight);
|
||||
_depth = bx::max<uint16_t>(1, _depth);
|
||||
_numLayers = bx::max<uint16_t>(1, _numLayers);
|
||||
|
||||
const uint8_t numMips = _hasMips ? imageGetNumMips(_format, _width, _height, _depth) : 1;
|
||||
uint32_t size = imageGetSize(NULL, _width, _height, _depth, _cubeMap, _hasMips, _numLayers, _format);
|
||||
@@ -3617,15 +3746,15 @@ namespace bimg
|
||||
{ KTX_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, KTX_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT, KTX_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, KTX_ZERO, }, // PTC14A
|
||||
{ KTX_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG, KTX_ZERO, KTX_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG, KTX_ZERO, }, // PTC22
|
||||
{ KTX_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG, KTX_ZERO, KTX_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG, KTX_ZERO, }, // PTC24
|
||||
{ KTX_ATC_RGB_AMD, KTX_ZERO, KTX_ATC_RGB_AMD, KTX_ZERO, }, // ATC
|
||||
{ KTX_ATC_RGBA_EXPLICIT_ALPHA_AMD, KTX_ZERO, KTX_ATC_RGBA_EXPLICIT_ALPHA_AMD, KTX_ZERO, }, // ATCE
|
||||
{ KTX_ATC_RGBA_INTERPOLATED_ALPHA_AMD, KTX_ZERO, KTX_ATC_RGBA_INTERPOLATED_ALPHA_AMD, KTX_ZERO, }, // ATCI
|
||||
{ KTX_COMPRESSED_RGBA_ASTC_4x4_KHR, KTX_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, KTX_COMPRESSED_RGBA_ASTC_4x4_KHR, KTX_ZERO, }, // ASTC4x4
|
||||
{ KTX_COMPRESSED_RGBA_ASTC_5x5_KHR, KTX_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, KTX_COMPRESSED_RGBA_ASTC_5x5_KHR, KTX_ZERO, }, // ASTC5x5
|
||||
{ KTX_COMPRESSED_RGBA_ASTC_6x6_KHR, KTX_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, KTX_COMPRESSED_RGBA_ASTC_6x6_KHR, KTX_ZERO, }, // ASTC6x6
|
||||
{ KTX_COMPRESSED_RGBA_ASTC_8x5_KHR, KTX_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, KTX_COMPRESSED_RGBA_ASTC_8x5_KHR, KTX_ZERO, }, // ASTC8x5
|
||||
{ KTX_COMPRESSED_RGBA_ASTC_8x6_KHR, KTX_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, KTX_COMPRESSED_RGBA_ASTC_8x6_KHR, KTX_ZERO, }, // ASTC8x6
|
||||
{ KTX_COMPRESSED_RGBA_ASTC_10x5_KHR, KTX_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, KTX_COMPRESSED_RGBA_ASTC_10x5_KHR, KTX_ZERO, }, // ASTC10x5
|
||||
{ KTX_ATC_RGB_AMD, KTX_ZERO, KTX_ATC_RGB_AMD, KTX_ZERO, }, // ATC
|
||||
{ KTX_ATC_RGBA_EXPLICIT_ALPHA_AMD, KTX_ZERO, KTX_ATC_RGBA_EXPLICIT_ALPHA_AMD, KTX_ZERO, }, // ATCE
|
||||
{ KTX_ATC_RGBA_INTERPOLATED_ALPHA_AMD, KTX_ZERO, KTX_ATC_RGBA_INTERPOLATED_ALPHA_AMD, KTX_ZERO, }, // ATCI
|
||||
{ KTX_COMPRESSED_RGBA_ASTC_4x4_KHR, KTX_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, KTX_COMPRESSED_RGBA_ASTC_4x4_KHR, KTX_ZERO, }, // ASTC4x4
|
||||
{ KTX_COMPRESSED_RGBA_ASTC_5x5_KHR, KTX_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, KTX_COMPRESSED_RGBA_ASTC_5x5_KHR, KTX_ZERO, }, // ASTC5x5
|
||||
{ KTX_COMPRESSED_RGBA_ASTC_6x6_KHR, KTX_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, KTX_COMPRESSED_RGBA_ASTC_6x6_KHR, KTX_ZERO, }, // ASTC6x6
|
||||
{ KTX_COMPRESSED_RGBA_ASTC_8x5_KHR, KTX_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, KTX_COMPRESSED_RGBA_ASTC_8x5_KHR, KTX_ZERO, }, // ASTC8x5
|
||||
{ KTX_COMPRESSED_RGBA_ASTC_8x6_KHR, KTX_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, KTX_COMPRESSED_RGBA_ASTC_8x6_KHR, KTX_ZERO, }, // ASTC8x6
|
||||
{ KTX_COMPRESSED_RGBA_ASTC_10x5_KHR, KTX_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, KTX_COMPRESSED_RGBA_ASTC_10x5_KHR, KTX_ZERO, }, // ASTC10x5
|
||||
{ KTX_ZERO, KTX_ZERO, KTX_ZERO, KTX_ZERO, }, // Unknown
|
||||
{ KTX_ZERO, KTX_ZERO, KTX_ZERO, KTX_ZERO, }, // R1
|
||||
{ KTX_ALPHA, KTX_ZERO, KTX_ALPHA, KTX_UNSIGNED_BYTE, }, // A8
|
||||
@@ -3784,8 +3913,8 @@ namespace bimg
|
||||
_imageContainer.m_depth = depth;
|
||||
_imageContainer.m_format = format;
|
||||
_imageContainer.m_orientation = Orientation::R0;
|
||||
_imageContainer.m_numLayers = uint16_t(bx::uint32_max(numberOfArrayElements, 1) );
|
||||
_imageContainer.m_numMips = uint8_t(bx::uint32_max(numMips, 1) );
|
||||
_imageContainer.m_numLayers = uint16_t(bx::max<uint32_t>(numberOfArrayElements, 1) );
|
||||
_imageContainer.m_numMips = uint8_t(bx::max<uint32_t>(numMips, 1) );
|
||||
_imageContainer.m_hasAlpha = hasAlpha;
|
||||
_imageContainer.m_cubeMap = numFaces > 1;
|
||||
_imageContainer.m_ktx = true;
|
||||
@@ -3950,7 +4079,7 @@ namespace bimg
|
||||
_imageContainer.m_format = format;
|
||||
_imageContainer.m_orientation = Orientation::R0;
|
||||
_imageContainer.m_numLayers = 1;
|
||||
_imageContainer.m_numMips = uint8_t(bx::uint32_max(numMips, 1) );
|
||||
_imageContainer.m_numMips = uint8_t(bx::max<uint32_t>(numMips, 1) );
|
||||
_imageContainer.m_hasAlpha = hasAlpha;
|
||||
_imageContainer.m_cubeMap = numFaces > 1;
|
||||
_imageContainer.m_ktx = false;
|
||||
@@ -4605,28 +4734,35 @@ namespace bimg
|
||||
|
||||
for (uint8_t lod = 0, num = _imageContainer.m_numMips; lod < num; ++lod)
|
||||
{
|
||||
uint32_t sourceSize = bx::toHostEndian(*(const uint32_t*)&data[offset], _imageContainer.m_ktxLE);
|
||||
width = bx::max<uint32_t>(blockWidth * minBlockX, ( (width + blockWidth - 1) / blockWidth )*blockWidth);
|
||||
height = bx::max<uint32_t>(blockHeight * minBlockY, ( (height + blockHeight - 1) / blockHeight)*blockHeight);
|
||||
depth = bx::max<uint32_t>(1, depth);
|
||||
|
||||
const uint32_t mipSize = width/blockWidth * height/blockHeight * depth * blockSize;
|
||||
if (mipSize != width*height*depth*bpp/8)
|
||||
{
|
||||
BX_TRACE("x");
|
||||
}
|
||||
|
||||
const uint32_t size = mipSize*numSides;
|
||||
uint32_t imageSize = bx::toHostEndian(*(const uint32_t*)&data[offset], _imageContainer.m_ktxLE);
|
||||
BX_CHECK(size == imageSize, "KTX: Image size mismatch %d (expected %d).", size, imageSize);
|
||||
BX_UNUSED(size, imageSize);
|
||||
|
||||
offset += sizeof(uint32_t);
|
||||
|
||||
depth = bx::uint32_max(1, depth);
|
||||
|
||||
uint32_t blocksX = bx::uint32_max(minBlockX, ((width + blockWidth - 1) / blockWidth ));
|
||||
uint32_t blocksY = bx::uint32_max(minBlockY, ((height + blockHeight - 1) / blockHeight));
|
||||
|
||||
uint32_t destSize = blocksX * blocksY * blockSize * depth;
|
||||
|
||||
BX_CHECK(sourceSize == destSize, "KTX: Image size mismatch %d (expected %d).", sourceSize, destSize);
|
||||
|
||||
for (uint16_t side = 0; side < numSides; ++side)
|
||||
{
|
||||
BX_CHECK(offset <= _size, "Reading past size of data buffer! (offset %d, size %d)", offset, _size);
|
||||
|
||||
if (side == _side
|
||||
&& lod == _lod)
|
||||
{
|
||||
_mip.m_width = blocksX * blockWidth;
|
||||
_mip.m_height = blocksY * blockHeight;
|
||||
_mip.m_width = width;
|
||||
_mip.m_height = height;
|
||||
_mip.m_depth = depth;
|
||||
_mip.m_blockSize = blockSize;
|
||||
_mip.m_size = destSize;
|
||||
_mip.m_size = mipSize;
|
||||
_mip.m_data = &data[offset];
|
||||
_mip.m_bpp = bpp;
|
||||
_mip.m_format = format;
|
||||
@@ -4634,9 +4770,8 @@ namespace bimg
|
||||
return true;
|
||||
}
|
||||
|
||||
offset += sourceSize;
|
||||
offset += mipSize;
|
||||
|
||||
BX_CHECK(offset <= _size, "Reading past size of data buffer! (offset %d, size %d)", offset, _size);
|
||||
BX_UNUSED(_size);
|
||||
}
|
||||
|
||||
@@ -4655,21 +4790,22 @@ namespace bimg
|
||||
|
||||
for (uint8_t lod = 0, num = _imageContainer.m_numMips; lod < num; ++lod)
|
||||
{
|
||||
depth = bx::uint32_max(1, depth);
|
||||
BX_CHECK(offset <= _size, "Reading past size of data buffer! (offset %d, size %d)", offset, _size);
|
||||
|
||||
uint32_t blocksX = bx::uint32_max(minBlockX, ((width + blockWidth - 1) / blockWidth ));
|
||||
uint32_t blocksY = bx::uint32_max(minBlockY, ((height + blockHeight - 1) / blockHeight));
|
||||
width = bx::max<uint32_t>(blockWidth * minBlockX, ( (width + blockWidth - 1) / blockWidth )*blockWidth);
|
||||
height = bx::max<uint32_t>(blockHeight * minBlockY, ( (height + blockHeight - 1) / blockHeight)*blockHeight);
|
||||
depth = bx::max<uint32_t>(1, depth);
|
||||
|
||||
uint32_t size = blocksX * blocksY * blockSize * depth;
|
||||
uint32_t mipSize = width/blockWidth * height/blockHeight * depth * blockSize;
|
||||
|
||||
if (side == _side
|
||||
&& lod == _lod)
|
||||
{
|
||||
_mip.m_width = blocksX * blockWidth;
|
||||
_mip.m_height = blocksY * blockHeight;
|
||||
_mip.m_width = width;
|
||||
_mip.m_height = height;
|
||||
_mip.m_depth = depth;
|
||||
_mip.m_blockSize = blockSize;
|
||||
_mip.m_size = size;
|
||||
_mip.m_size = mipSize;
|
||||
_mip.m_data = &data[offset];
|
||||
_mip.m_bpp = bpp;
|
||||
_mip.m_format = format;
|
||||
@@ -4677,9 +4813,8 @@ namespace bimg
|
||||
return true;
|
||||
}
|
||||
|
||||
offset += size;
|
||||
offset += mipSize;
|
||||
|
||||
BX_CHECK(offset <= _size, "Reading past size of data buffer! (offset %d, size %d)", offset, _size);
|
||||
BX_UNUSED(_size);
|
||||
|
||||
width >>= 1;
|
||||
@@ -4891,13 +5026,15 @@ namespace bimg
|
||||
total += bx::writeLE(_writer, uint32_t(18*4+1), _err);
|
||||
|
||||
const uint8_t cdata[] = { 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 };
|
||||
total += bx::write(_writer, 'R', _err);
|
||||
total += bx::write(_writer, cdata, BX_COUNTOF(cdata), _err);
|
||||
total += bx::write(_writer, 'G', _err);
|
||||
// Order is always ABGR order because Photoshop and GIMP ignore these fields and
|
||||
// assume it's in ABGR order.
|
||||
total += bx::write(_writer, 'A', _err);
|
||||
total += bx::write(_writer, cdata, BX_COUNTOF(cdata), _err);
|
||||
total += bx::write(_writer, 'B', _err);
|
||||
total += bx::write(_writer, cdata, BX_COUNTOF(cdata), _err);
|
||||
total += bx::write(_writer, 'A', _err);
|
||||
total += bx::write(_writer, 'G', _err);
|
||||
total += bx::write(_writer, cdata, BX_COUNTOF(cdata), _err);
|
||||
total += bx::write(_writer, 'R', _err);
|
||||
total += bx::write(_writer, cdata, BX_COUNTOF(cdata), _err);
|
||||
total += bx::write(_writer, '\0', _err);
|
||||
|
||||
@@ -4973,12 +5110,7 @@ namespace bimg
|
||||
|
||||
for (uint32_t xx = 0; xx < _width && _err->isOk(); ++xx)
|
||||
{
|
||||
total += bx::write(_writer, &data[xx*bpp/8+0*bytesPerChannel], bytesPerChannel, _err);
|
||||
}
|
||||
|
||||
for (uint32_t xx = 0; xx < _width && _err->isOk(); ++xx)
|
||||
{
|
||||
total += bx::write(_writer, &data[xx*bpp/8+1*bytesPerChannel], bytesPerChannel, _err);
|
||||
total += bx::write(_writer, &data[xx*bpp/8+3*bytesPerChannel], bytesPerChannel, _err);
|
||||
}
|
||||
|
||||
for (uint32_t xx = 0; xx < _width && _err->isOk(); ++xx)
|
||||
@@ -4988,7 +5120,53 @@ namespace bimg
|
||||
|
||||
for (uint32_t xx = 0; xx < _width && _err->isOk(); ++xx)
|
||||
{
|
||||
total += bx::write(_writer, &data[xx*bpp/8+3*bytesPerChannel], bytesPerChannel, _err);
|
||||
total += bx::write(_writer, &data[xx*bpp/8+1*bytesPerChannel], bytesPerChannel, _err);
|
||||
}
|
||||
|
||||
for (uint32_t xx = 0; xx < _width && _err->isOk(); ++xx)
|
||||
{
|
||||
total += bx::write(_writer, &data[xx*bpp/8+0*bytesPerChannel], bytesPerChannel, _err);
|
||||
}
|
||||
|
||||
data += _srcPitch;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
int32_t imageWriteHdr(bx::WriterI* _writer, uint32_t _width, uint32_t _height, uint32_t _srcPitch, const void* _src, TextureFormat::Enum _format, bool _yflip, bx::Error* _err)
|
||||
{
|
||||
BX_ERROR_SCOPE(_err);
|
||||
|
||||
int32_t total = 0;
|
||||
total += bx::write(_writer, "#?RADIANCE\n" , _err);
|
||||
total += bx::write(_writer, "FORMAT=32-bit_rle_rgbe\n" , _err);
|
||||
total += bx::write(_writer, '\n' , _err);
|
||||
|
||||
total += bx::writePrintf(_writer, "%cY %d +X %d\n", _yflip ? '+' : '-', _height, _width);
|
||||
|
||||
UnpackFn unpack = getUnpack(_format);
|
||||
const uint32_t bpp = getBitsPerPixel(_format);
|
||||
|
||||
const uint8_t* data = (const uint8_t*)_src;
|
||||
for (uint32_t yy = 0; yy < _height && _err->isOk(); ++yy)
|
||||
{
|
||||
for (uint32_t xx = 0; xx < _width && _err->isOk(); ++xx)
|
||||
{
|
||||
float rgba[4];
|
||||
unpack(rgba, &data[xx*bpp/8]);
|
||||
|
||||
const float maxVal = bx::max(rgba[0], rgba[1], rgba[2]);
|
||||
const float exp = bx::ceil(bx::log2(maxVal) );
|
||||
const float toRgb8 = 255.0f * 1.0f/bx::ldexp(1.0f, int(exp) );
|
||||
|
||||
uint8_t rgbe[4];
|
||||
rgbe[0] = uint8_t(rgba[0] * toRgb8);
|
||||
rgbe[1] = uint8_t(rgba[1] * toRgb8);
|
||||
rgbe[2] = uint8_t(rgba[2] * toRgb8);
|
||||
rgbe[3] = uint8_t(exp+128.0f);
|
||||
|
||||
total += bx::write(_writer, rgbe, 4, _err);
|
||||
}
|
||||
|
||||
data += _srcPitch;
|
||||
@@ -5191,15 +5369,15 @@ namespace bimg
|
||||
}
|
||||
|
||||
const ImageBlockInfo& blockInfo = s_imageBlockInfo[_format];
|
||||
const uint8_t bpp = blockInfo.bitsPerPixel;
|
||||
const uint32_t blockWidth = blockInfo.blockWidth;
|
||||
const uint32_t blockHeight = blockInfo.blockHeight;
|
||||
const uint32_t minBlockX = blockInfo.minBlockX;
|
||||
const uint32_t minBlockY = blockInfo.minBlockY;
|
||||
const uint8_t blockSize = blockInfo.blockSize;
|
||||
|
||||
const uint8_t* src = (const uint8_t*)_src;
|
||||
|
||||
const uint32_t numLayers = bx::uint32_max(_numLayers, 1);
|
||||
const uint32_t numLayers = bx::max<uint32_t>(_numLayers, 1);
|
||||
const uint32_t numSides = _cubeMap ? 6 : 1;
|
||||
|
||||
uint32_t width = _width;
|
||||
@@ -5208,12 +5386,12 @@ namespace bimg
|
||||
|
||||
for (uint8_t lod = 0; lod < _numMips && _err->isOk(); ++lod)
|
||||
{
|
||||
width = bx::uint32_max(blockWidth * minBlockX, ( (width + blockWidth - 1) / blockWidth )*blockWidth);
|
||||
height = bx::uint32_max(blockHeight * minBlockY, ( (height + blockHeight - 1) / blockHeight)*blockHeight);
|
||||
depth = bx::uint32_max(1, depth);
|
||||
width = bx::max<uint32_t>(blockWidth * minBlockX, ( (width + blockWidth - 1) / blockWidth )*blockWidth);
|
||||
height = bx::max<uint32_t>(blockHeight * minBlockY, ( (height + blockHeight - 1) / blockHeight)*blockHeight);
|
||||
depth = bx::max<uint32_t>(1, depth);
|
||||
|
||||
const uint32_t mipSize = width*height*depth*bpp/8;
|
||||
const uint32_t size = mipSize*numLayers*numSides;
|
||||
const uint32_t mipSize = width/blockWidth * height/blockHeight * depth * blockSize;
|
||||
const uint32_t size = mipSize * numLayers * numSides;
|
||||
total += bx::write(_writer, size, _err);
|
||||
|
||||
for (uint32_t layer = 0; layer < numLayers && _err->isOk(); ++layer)
|
||||
@@ -5255,7 +5433,7 @@ namespace bimg
|
||||
}
|
||||
|
||||
const uint32_t numMips = _imageContainer.m_numMips;
|
||||
const uint32_t numLayers = bx::uint32_max(_imageContainer.m_numLayers, 1);
|
||||
const uint32_t numLayers = bx::max<uint32_t>(_imageContainer.m_numLayers, 1);
|
||||
const uint32_t numSides = _imageContainer.m_cubeMap ? 6 : 1;
|
||||
|
||||
for (uint8_t lod = 0; lod < numMips && _err->isOk(); ++lod)
|
||||
@@ -5281,185 +5459,4 @@ namespace bimg
|
||||
return total;
|
||||
}
|
||||
|
||||
// +----------+
|
||||
// |-z 2|
|
||||
// | ^ +y |
|
||||
// | | |
|
||||
// | +---->+x |
|
||||
// +----------+----------+----------+----------+
|
||||
// |+y 1|+y 4|+y 0|+y 5|
|
||||
// | ^ -x | ^ +z | ^ +x | ^ -z |
|
||||
// | | | | | | | | |
|
||||
// | +---->+z | +---->+x | +---->-z | +---->-x |
|
||||
// +----------+----------+----------+----------+
|
||||
// |+z 3|
|
||||
// | ^ -y |
|
||||
// | | |
|
||||
// | +---->+x |
|
||||
// +----------+
|
||||
//
|
||||
struct CubeMapFace
|
||||
{
|
||||
float uv[3][3];
|
||||
};
|
||||
|
||||
static const CubeMapFace s_cubeMapFace[] =
|
||||
{
|
||||
{{ // +x face
|
||||
{ 0.0f, 0.0f, -1.0f }, // u -> -z
|
||||
{ 0.0f, -1.0f, 0.0f }, // v -> -y
|
||||
{ 1.0f, 0.0f, 0.0f }, // +x face
|
||||
}},
|
||||
{{ // -x face
|
||||
{ 0.0f, 0.0f, 1.0f }, // u -> +z
|
||||
{ 0.0f, -1.0f, 0.0f }, // v -> -y
|
||||
{ -1.0f, 0.0f, 0.0f }, // -x face
|
||||
}},
|
||||
{{ // +y face
|
||||
{ 1.0f, 0.0f, 0.0f }, // u -> +x
|
||||
{ 0.0f, 0.0f, 1.0f }, // v -> +z
|
||||
{ 0.0f, 1.0f, 0.0f }, // +y face
|
||||
}},
|
||||
{{ // -y face
|
||||
{ 1.0f, 0.0f, 0.0f }, // u -> +x
|
||||
{ 0.0f, 0.0f, -1.0f }, // v -> -z
|
||||
{ 0.0f, -1.0f, 0.0f }, // -y face
|
||||
}},
|
||||
{{ // +z face
|
||||
{ 1.0f, 0.0f, 0.0f }, // u -> +x
|
||||
{ 0.0f, -1.0f, 0.0f }, // v -> -y
|
||||
{ 0.0f, 0.0f, 1.0f }, // +z face
|
||||
}},
|
||||
{{ // -z face
|
||||
{ -1.0f, 0.0f, 0.0f }, // u -> -x
|
||||
{ 0.0f, -1.0f, 0.0f }, // v -> -y
|
||||
{ 0.0f, 0.0f, -1.0f }, // -z face
|
||||
}},
|
||||
};
|
||||
|
||||
/// _u and _v should be center addressing and in [-1.0+invSize..1.0-invSize] range.
|
||||
void texelUvToDir(float* _result, uint8_t _side, float _u, float _v)
|
||||
{
|
||||
const CubeMapFace& face = s_cubeMapFace[_side];
|
||||
|
||||
float tmp[3];
|
||||
tmp[0] = face.uv[0][0] * _u + face.uv[1][0] * _v + face.uv[2][0];
|
||||
tmp[1] = face.uv[0][1] * _u + face.uv[1][1] * _v + face.uv[2][1];
|
||||
tmp[2] = face.uv[0][2] * _u + face.uv[1][2] * _v + face.uv[2][2];
|
||||
bx::vec3Norm(_result, tmp);
|
||||
}
|
||||
|
||||
ImageContainer* imageCubemapFromLatLongRgba32F(bx::AllocatorI* _allocator, const ImageContainer& _input, bool _useBilinearInterpolation, bx::Error* _err)
|
||||
{
|
||||
BX_ERROR_SCOPE(_err);
|
||||
|
||||
if (_input.m_depth != 1
|
||||
&& _input.m_numLayers != 1
|
||||
&& _input.m_format != TextureFormat::RGBA32F
|
||||
&& _input.m_width/2 != _input.m_height)
|
||||
{
|
||||
BX_ERROR_SET(_err, BIMG_ERROR, "Input image format is not equirectangular projection.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const uint32_t srcWidthMinusOne = _input.m_width-1;
|
||||
const uint32_t srcHeightMinusOne = _input.m_height-1;
|
||||
const uint32_t srcPitch = _input.m_width*16;
|
||||
const uint32_t dstWidth = _input.m_height/2;
|
||||
const uint32_t dstPitch = dstWidth*16;
|
||||
const float invDstWidth = 1.0f / float(dstWidth);
|
||||
|
||||
ImageContainer* output = imageAlloc(_allocator
|
||||
, _input.m_format
|
||||
, uint16_t(dstWidth)
|
||||
, uint16_t(dstWidth)
|
||||
, uint16_t(1)
|
||||
, 1
|
||||
, true
|
||||
, false
|
||||
);
|
||||
|
||||
const uint8_t* srcData = (const uint8_t*)_input.m_data;
|
||||
|
||||
for (uint8_t side = 0; side < 6 && _err->isOk(); ++side)
|
||||
{
|
||||
ImageMip mip;
|
||||
imageGetRawData(*output, side, 0, output->m_data, output->m_size, mip);
|
||||
|
||||
for (uint32_t yy = 0; yy < dstWidth; ++yy)
|
||||
{
|
||||
for (uint32_t xx = 0; xx < dstWidth; ++xx)
|
||||
{
|
||||
float* dstData = (float*)&mip.m_data[yy*dstPitch+xx*16];
|
||||
|
||||
const float uu = 2.0f*xx*invDstWidth - 1.0f;
|
||||
const float vv = 2.0f*yy*invDstWidth - 1.0f;
|
||||
|
||||
float dir[3];
|
||||
texelUvToDir(dir, side, uu, vv);
|
||||
|
||||
float srcU, srcV;
|
||||
bx::vec3ToLatLong(&srcU, &srcV, dir);
|
||||
|
||||
srcU *= srcWidthMinusOne;
|
||||
srcV *= srcHeightMinusOne;
|
||||
|
||||
if (_useBilinearInterpolation)
|
||||
{
|
||||
const uint32_t x0 = uint32_t(srcU);
|
||||
const uint32_t y0 = uint32_t(srcV);
|
||||
const uint32_t x1 = bx::min(x0 + 1, srcWidthMinusOne);
|
||||
const uint32_t y1 = bx::min(y0 + 1, srcHeightMinusOne);
|
||||
|
||||
const float* src0 = (const float*)&srcData[y0*srcPitch + x0*16];
|
||||
const float* src1 = (const float*)&srcData[y0*srcPitch + x1*16];
|
||||
const float* src2 = (const float*)&srcData[y1*srcPitch + x0*16];
|
||||
const float* src3 = (const float*)&srcData[y1*srcPitch + x1*16];
|
||||
|
||||
const float tx = srcU - float(int32_t(x0) );
|
||||
const float ty = srcV - float(int32_t(y0) );
|
||||
const float omtx = 1.0f - tx;
|
||||
const float omty = 1.0f - ty;
|
||||
|
||||
float p0[4];
|
||||
bx::vec4Mul(p0, src0, omtx*omty);
|
||||
|
||||
float p1[4];
|
||||
bx::vec4Mul(p1, src1, tx*omty);
|
||||
|
||||
float p2[4];
|
||||
bx::vec4Mul(p2, src2, omtx*ty);
|
||||
|
||||
float p3[4];
|
||||
bx::vec4Mul(p3, src3, tx*ty);
|
||||
|
||||
const float rr = p0[0] + p1[0] + p2[0] + p3[0];
|
||||
const float gg = p0[1] + p1[1] + p2[1] + p3[1];
|
||||
const float bb = p0[2] + p1[2] + p2[2] + p3[2];
|
||||
const float aa = p0[3] + p1[3] + p2[3] + p3[3];
|
||||
|
||||
dstData[0] = rr;
|
||||
dstData[1] = gg;
|
||||
dstData[2] = bb;
|
||||
dstData[3] = aa;
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint32_t x0 = uint32_t(srcU);
|
||||
const uint32_t y0 = uint32_t(srcV);
|
||||
const float* src0 = (const float*)&srcData[y0*srcPitch + x0*16];
|
||||
|
||||
dstData[0] = src0[0];
|
||||
dstData[1] = src0[1];
|
||||
dstData[2] = src0[2];
|
||||
dstData[3] = src0[3];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
} // namespace bimg
|
||||
|
||||
1207
src/image_cubemap_filter.cpp
Normal file
1207
src/image_cubemap_filter.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -228,7 +228,10 @@ namespace bimg
|
||||
break;
|
||||
|
||||
default:
|
||||
BX_ERROR_SET(_err, BIMG_ERROR, "Unable to convert between input/output formats!");
|
||||
if (!imageConvert(_allocator, _dst, _dstFormat, _src, _srcFormat, _width, _height, 1) )
|
||||
{
|
||||
BX_ERROR_SET(_err, BIMG_ERROR, "Unable to convert between input/output formats!");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -260,17 +263,18 @@ namespace bimg
|
||||
imageGetRawData(*output, side, lod, output->m_data, output->m_size, dstMip);
|
||||
uint8_t* dstData = const_cast<uint8_t*>(dstMip.m_data);
|
||||
|
||||
imageEncode(_allocator
|
||||
, dstData
|
||||
, mip.m_data
|
||||
, mip.m_format
|
||||
, mip.m_width
|
||||
, mip.m_height
|
||||
, mip.m_depth
|
||||
, _dstFormat
|
||||
, _quality
|
||||
, &err
|
||||
);
|
||||
imageEncode(
|
||||
_allocator
|
||||
, dstData
|
||||
, mip.m_data
|
||||
, mip.m_format
|
||||
, mip.m_width
|
||||
, mip.m_height
|
||||
, mip.m_depth
|
||||
, _dstFormat
|
||||
, _quality
|
||||
, &err
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,25 +26,12 @@
|
||||
#include <string>
|
||||
|
||||
#define BIMG_TEXTUREC_VERSION_MAJOR 1
|
||||
#define BIMG_TEXTUREC_VERSION_MINOR 15
|
||||
#define BIMG_TEXTUREC_VERSION_MINOR 17
|
||||
|
||||
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"
|
||||
@@ -56,6 +43,9 @@ 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"
|
||||
, maxSize
|
||||
, edge
|
||||
, bimg::getName(format)
|
||||
@@ -64,20 +54,25 @@ struct Options
|
||||
, iqa ? "true" : "false"
|
||||
, pma ? "true" : "false"
|
||||
, sdf ? "true" : "false"
|
||||
, radiance ? "true" : "false"
|
||||
, equirect ? "true" : "false"
|
||||
, strip ? "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;
|
||||
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;
|
||||
};
|
||||
|
||||
void imageRgba32fNormalize(void* _dst, uint32_t _width, uint32_t _height, uint32_t _srcPitch, const void* _src)
|
||||
@@ -168,9 +163,47 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
|
||||
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)
|
||||
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,9 +237,10 @@ 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)
|
||||
@@ -261,13 +295,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 +323,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
|
||||
@@ -749,7 +815,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"
|
||||
@@ -766,13 +832,15 @@ void help(const char* _error = NULL, bool _showHelp = true)
|
||||
" -q <quality> Encoding quality (default, fastest, highest).\n"
|
||||
" -m, --mips Generate mip-maps.\n"
|
||||
" -n, --normalmap Input texture is normal map.\n"
|
||||
" --equirect Input texture equirectangular projection of cubemap.\n"
|
||||
" --equirect Input texture is equirectangular projection of cubemap.\n"
|
||||
" --strip Input texture is horizontal strip of cubemap.\n"
|
||||
" --sdf <edge> Compute SDF texture.\n"
|
||||
" --ref <alpha> Alpha reference value.\n"
|
||||
" --iqa Image Quality Assessment\n"
|
||||
" --pma Premultiply alpha into RGB channel.\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"
|
||||
" --validate *DEBUG* Validate that output image produced matches after loading.\n"
|
||||
|
||||
@@ -860,6 +928,7 @@ int main(int _argc, const char* _argv[])
|
||||
saveAs = NULL == saveAs ? bx::strFindI(outputFileName, ".dds") : saveAs;
|
||||
saveAs = NULL == saveAs ? bx::strFindI(outputFileName, ".png") : saveAs;
|
||||
saveAs = NULL == saveAs ? bx::strFindI(outputFileName, ".exr") : saveAs;
|
||||
saveAs = NULL == saveAs ? bx::strFindI(outputFileName, ".hdr") : saveAs;
|
||||
if (NULL == saveAs)
|
||||
{
|
||||
help("Output file format must be specified.");
|
||||
@@ -890,16 +959,28 @@ int main(int _argc, const char* _argv[])
|
||||
}
|
||||
}
|
||||
|
||||
options.mips = cmdLine.hasArg('m', "mips");
|
||||
options.normalMap = cmdLine.hasArg('n', "normalmap");
|
||||
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");
|
||||
|
||||
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 size failed.");
|
||||
return bx::kExitFailure;
|
||||
}
|
||||
}
|
||||
|
||||
options.format = bimg::TextureFormat::Count;
|
||||
@@ -954,6 +1035,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;
|
||||
@@ -1019,7 +1115,8 @@ int main(int _argc, const char* _argv[])
|
||||
, mip.m_data
|
||||
, output->m_format
|
||||
, false
|
||||
, &err);
|
||||
, &err
|
||||
);
|
||||
}
|
||||
else if (NULL != bx::strFindI(saveAs, "exr") )
|
||||
{
|
||||
@@ -1032,7 +1129,22 @@ int main(int _argc, const char* _argv[])
|
||||
, mip.m_data
|
||||
, output->m_format
|
||||
, false
|
||||
, &err);
|
||||
, &err
|
||||
);
|
||||
}
|
||||
else if (NULL != bx::strFindI(saveAs, "hdr") )
|
||||
{
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user