Add support for resizing textures with stb in TextureTool
This commit is contained in:
@@ -569,11 +569,9 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path
|
||||
{
|
||||
auto& tmpImg = GET_TMP_IMG();
|
||||
|
||||
LOG(Info, "Resizing texture from {0}x{1} to {2}x{3}.", sourceWidth, sourceHeight, width, height);
|
||||
|
||||
// During resizing we need to keep texture aspect ratio
|
||||
const bool keepAspectRation = false; // TODO: expose as import option
|
||||
if (keepAspectRation)
|
||||
const bool keepAspectRatio = false; // TODO: expose as import option
|
||||
if (keepAspectRatio)
|
||||
{
|
||||
const float aspectRatio = static_cast<float>(sourceWidth) / sourceHeight;
|
||||
if (width >= height)
|
||||
@@ -583,6 +581,7 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path
|
||||
}
|
||||
|
||||
// Resize source texture
|
||||
LOG(Info, "Resizing texture from {0}x{1} to {2}x{3}.", sourceWidth, sourceHeight, width, height);
|
||||
result = DirectX::Resize(*currentImage->GetImages(), width, height, DirectX::TEX_FILTER_LINEAR, tmpImg);
|
||||
if (FAILED(result))
|
||||
{
|
||||
|
||||
@@ -354,6 +354,8 @@ bool TextureTool::Resize(TextureData& dst, const TextureData& src, int32 dstWidt
|
||||
|
||||
#if COMPILE_WITH_DIRECTXTEX
|
||||
return ResizeDirectXTex(dst, src, dstWidth, dstHeight);
|
||||
#elif COMPILE_WITH_STB
|
||||
return ResizeStb(dst, src, dstWidth, dstHeight);
|
||||
#else
|
||||
LOG(Warning, "Resizing textures is not supported on this platform.");
|
||||
return true;
|
||||
|
||||
@@ -291,6 +291,7 @@ private:
|
||||
#if COMPILE_WITH_STB
|
||||
static bool ExportTextureStb(ImageType type, const StringView& path, const TextureData& textureData);
|
||||
static bool ImportTextureStb(ImageType type, const StringView& path, TextureData& textureData, bool& hasAlpha);
|
||||
static bool ResizeStb(TextureData& dst, const TextureData& src, int32 dstWidth, int32 dstHeight);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -15,10 +15,6 @@
|
||||
#define STBI_REALLOC(p, newsz) AllocatorExt::Realloc(p, newsz)
|
||||
#define STBI_REALLOC_SIZED(p, oldsz, newsz) AllocatorExt::Realloc(p, oldsz, newsz)
|
||||
#define STBI_FREE(p) Allocator::Free(p)
|
||||
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#include <ThirdParty/stb/stb_image_write.h>
|
||||
|
||||
#define STBI_NO_PSD
|
||||
#define STBI_NO_PIC
|
||||
#define STBI_NO_PNM
|
||||
@@ -27,6 +23,20 @@
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <ThirdParty/stb/stb_image.h>
|
||||
|
||||
#define STBIW_ASSERT(x) ASSERT(x)
|
||||
#define STBIW_MALLOC(sz) Allocator::Allocate(sz)
|
||||
#define STBIW_REALLOC(p, newsz) AllocatorExt::Realloc(p, newsz)
|
||||
#define STBIW_REALLOC_SIZED(p, oldsz, newsz) AllocatorExt::Realloc(p, oldsz, newsz)
|
||||
#define STBIW_FREE(p) Allocator::Free(p)
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#include <ThirdParty/stb/stb_image_write.h>
|
||||
|
||||
#define STBIR_ASSERT(x) ASSERT(x)
|
||||
#define STBIR_MALLOC(sz, c) Allocator::Allocate(sz)
|
||||
#define STBIR_FREE(p, c) Allocator::Free(p)
|
||||
#define STB_IMAGE_RESIZE_IMPLEMENTATION
|
||||
#include <ThirdParty/stb/stb_image_resize.h>
|
||||
|
||||
static void stbWrite(void* context, void* data, int size)
|
||||
{
|
||||
auto file = (FileWriteStream*)context;
|
||||
@@ -250,4 +260,100 @@ bool TextureTool::ImportTextureStb(ImageType type, const StringView& path, Textu
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TextureTool::ResizeStb(TextureData& dst, const TextureData& src, int32 dstWidth, int32 dstHeight)
|
||||
{
|
||||
// Setup
|
||||
auto arraySize = src.GetArraySize();
|
||||
dst.Width = dstWidth;
|
||||
dst.Height = dstHeight;
|
||||
dst.Depth = src.Depth;
|
||||
dst.Format = src.Format;
|
||||
dst.Items.Resize(arraySize);
|
||||
auto formatSize = PixelFormatExtensions::SizeInBytes(src.Format);
|
||||
auto components = PixelFormatExtensions::ComputeComponentsCount(src.Format);
|
||||
|
||||
// Resize all array slices
|
||||
for (int32 arrayIndex = 0; arrayIndex < arraySize; arrayIndex++)
|
||||
{
|
||||
const auto& srcSlice = src.Items[arrayIndex];
|
||||
auto& dstSlice = dst.Items[arrayIndex];
|
||||
auto mipLevels = srcSlice.Mips.Count();
|
||||
dstSlice.Mips.Resize(mipLevels);
|
||||
|
||||
// Resize all mip levels
|
||||
for (int32 mipIndex = 0; mipIndex < mipLevels; mipIndex++)
|
||||
{
|
||||
const auto& srcMip = srcSlice.Mips[mipIndex];
|
||||
auto& dstMip = dstSlice.Mips[mipIndex];
|
||||
auto srcMipWidth = srcMip.RowPitch / formatSize;
|
||||
auto srcMipHeight = srcMip.DepthPitch / srcMip.RowPitch;
|
||||
auto dstMipWidth = Math::Max(dstWidth << mipIndex, 1);
|
||||
auto dstMipHeight = Math::Max(dstHeight << mipIndex, 1);
|
||||
|
||||
// Allocate memory
|
||||
dstMip.RowPitch = dstMipWidth * formatSize;
|
||||
dstMip.DepthPitch = dstMip.RowPitch * dstMipHeight;
|
||||
dstMip.Lines = dstMipHeight;
|
||||
dstMip.Data.Allocate(dstMip.DepthPitch);
|
||||
|
||||
// Resize texture
|
||||
switch (src.Format)
|
||||
{
|
||||
case PixelFormat::R8_Typeless:
|
||||
case PixelFormat::R8_SInt:
|
||||
case PixelFormat::R8_SNorm:
|
||||
case PixelFormat::R8G8_Typeless:
|
||||
case PixelFormat::R8G8_SInt:
|
||||
case PixelFormat::R8G8_SNorm:
|
||||
case PixelFormat::R8G8B8A8_Typeless:
|
||||
case PixelFormat::R8G8B8A8_UNorm:
|
||||
case PixelFormat::R8G8B8A8_UInt:
|
||||
case PixelFormat::R8G8B8A8_SNorm:
|
||||
case PixelFormat::R8G8B8A8_SInt:
|
||||
case PixelFormat::B8G8R8A8_UNorm:
|
||||
case PixelFormat::B8G8R8X8_Typeless:
|
||||
case PixelFormat::B8G8R8X8_UNorm:
|
||||
{
|
||||
if (!stbir_resize_uint8((const uint8*)srcMip.Data.Get(), srcMipWidth, srcMipHeight, srcMip.RowPitch, (uint8*)dstMip.Data.Get(), dstMipWidth, dstMipHeight, dstMip.RowPitch, components))
|
||||
{
|
||||
LOG(Warning, "Cannot resize image.");
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PixelFormat::R8G8B8A8_UNorm_sRGB:
|
||||
case PixelFormat::B8G8R8A8_UNorm_sRGB:
|
||||
case PixelFormat::B8G8R8X8_UNorm_sRGB:
|
||||
{
|
||||
auto alphaChannel = src.Format == PixelFormat::B8G8R8X8_UNorm_sRGB ? STBIR_ALPHA_CHANNEL_NONE : 3;
|
||||
if (!stbir_resize_uint8_srgb((const uint8*)srcMip.Data.Get(), srcMipWidth, srcMipHeight, srcMip.RowPitch, (uint8*)dstMip.Data.Get(), dstMipWidth, dstMipHeight, dstMip.RowPitch, components, alphaChannel, 0))
|
||||
{
|
||||
LOG(Warning, "Cannot resize image.");
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PixelFormat::R32_Typeless:
|
||||
case PixelFormat::R32_Float:
|
||||
case PixelFormat::R32G32_Float:
|
||||
case PixelFormat::R32G32B32_Float:
|
||||
case PixelFormat::R32G32B32A32_Float:
|
||||
{
|
||||
if (!stbir_resize_float((const float*)srcMip.Data.Get(), srcMipWidth, srcMipHeight, srcMip.RowPitch, (float*)dstMip.Data.Get(), dstMipWidth, dstMipHeight, dstMip.RowPitch, components))
|
||||
{
|
||||
LOG(Warning, "Cannot resize image.");
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOG(Warning, "Cannot resize image. Unsupported format {0}", static_cast<int32>(src.Format));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
2631
Source/ThirdParty/stb/stb_image_resize.h
vendored
Normal file
2631
Source/ThirdParty/stb/stb_image_resize.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user