Skip to content

Commit

Permalink
Fix #3: force resizing to a multiple of 4 before compressing any text…
Browse files Browse the repository at this point in the history
…ure as BCn + tests
  • Loading branch information
robertos committed Dec 20, 2017
1 parent 2e018ff commit 4a3f028
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 4 deletions.
35 changes: 35 additions & 0 deletions glTF-Toolkit.Test/GLTFTextureCompressionUtilsTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ namespace Microsoft::glTF::Toolkit::Test
const char* c_baseColorPng = "Resources\\gltf\\WaterBottle_ORM\\WaterBottle_baseColor.png";
const char* c_baseColorBC7 = "Resources\\gltf\\WaterBottle_ORM\\WaterBottle_baseColor.DDS";
const char* c_waterBottleORMJson = "Resources\\gltf\\WaterBottle_ORM\\WaterBottle.gltf";
const char* c_nonMultipleOf4TextureJson = "Resources\\gltf\\TextureTest\\TextureTest.gltf";

TEST_METHOD(GLTFTextureCompressionUtils_CompressImage_BC7)
{
Expand Down Expand Up @@ -231,5 +232,39 @@ namespace Microsoft::glTF::Toolkit::Test
Assert::IsTrue(compressedDoc.images.Get(ddsImageId).uri.compare(9, expectedSuffix.size(), expectedSuffix) == 0); // The emissive texture should have mips and be BC7
});
}

TEST_METHOD(GLTFTextureCompressionUtils_CompressTextureAsDDS_NotMultipleOf4)
{
// This asset has all textures
TestUtils::LoadAndExecuteGLTFTest(c_nonMultipleOf4TextureJson, [](auto doc, auto path)
{
auto maxTextureSize = std::numeric_limits<size_t>::max();
auto generateMipMaps = false;
auto retainOriginalImages = true;
auto compressedDoc = GLTFTextureCompressionUtils::CompressTextureAsDDS(TestStreamReader(path), doc, doc.textures.Get("0"), TextureCompression::BC3, "", maxTextureSize, generateMipMaps, retainOriginalImages);

auto originalUri = compressedDoc.images.Get("0").uri;
auto compressedUri = compressedDoc.images.Get("1").uri;

auto basePath = TestUtils::GetBasePath(path.c_str());

// load original
DirectX::ScratchImage originalImage;
DirectX::TexMetadata originalInfo;
DirectX::LoadFromWICFile(WStringUtils::ToWString(basePath + originalUri).c_str(), DirectX::WIC_FLAGS_NONE, &originalInfo, originalImage);

Assert::IsTrue(101 == originalInfo.width);
Assert::IsTrue(51 == originalInfo.height);

// load compressed
DirectX::ScratchImage compressedImage;
DirectX::TexMetadata compressedInfo;
DirectX::LoadFromDDSFile(WStringUtils::ToWString(compressedUri).c_str(), DirectX::DDS_FLAGS_NONE, &compressedInfo, compressedImage);

// Check resize
Assert::IsTrue(104 == compressedInfo.width);
Assert::IsTrue(52 == compressedInfo.height);
});
}
};
}
Binary file added glTF-Toolkit.Test/Resources/gltf/TextureTest/0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions glTF-Toolkit.Test/Resources/gltf/TextureTest/TextureTest.gltf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"asset" : {
"version" : "2.0"
},
"textures": [
{
"sampler": 0,
"source": 0
}
],
"images": [
{
"uri": "0.png"
}
]
}
2 changes: 2 additions & 0 deletions glTF-Toolkit.Test/glTF-Toolkit.Test.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,15 @@
<None Include="packages.config" />
<None Include="Resources\gltf\CubeAsset3D.gltf" />
<None Include="Resources\gltf\CubeWithLOD.gltf" />
<None Include="Resources\gltf\TextureTest\TextureTest.gltf" />
<None Include="Resources\gltf\WaterBottle\WaterBottle.bin" />
<None Include="Resources\gltf\WaterBottle\WaterBottle.gltf" />
<None Include="Resources\gltf\WaterBottle_ORM\WaterBottle.bin" />
<None Include="Resources\gltf\WaterBottle_ORM\WaterBottle.gltf" />
<None Include="Resources\gltf\WaterBottle_ORM\WaterBottle_WindowsMR.gltf" />
</ItemGroup>
<ItemGroup>
<Image Include="Resources\gltf\TextureTest\0.png" />
<Image Include="Resources\gltf\WaterBottle\WaterBottle_baseColor.png" />
<Image Include="Resources\gltf\WaterBottle\WaterBottle_diffuse.png" />
<Image Include="Resources\gltf\WaterBottle\WaterBottle_emissive.png" />
Expand Down
9 changes: 9 additions & 0 deletions glTF-Toolkit.Test/glTF-Toolkit.Test.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
<Filter Include="Resources\WaterBottle_ORM">
<UniqueIdentifier>{c7fc3736-b68e-4f6d-b93b-1bb4eda5b1ff}</UniqueIdentifier>
</Filter>
<Filter Include="Resources\TextureTest">
<UniqueIdentifier>{e4d4222d-e5af-4dad-b539-28e2dc1c716a}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="Resources\gltf\CubeAsset3D.gltf">
Expand All @@ -45,6 +48,9 @@
<None Include="Resources\gltf\WaterBottle_ORM\WaterBottle_WindowsMR.gltf">
<Filter>Resources\WaterBottle_ORM</Filter>
</None>
<None Include="Resources\gltf\TextureTest\TextureTest.gltf">
<Filter>Resources\TextureTest</Filter>
</None>
</ItemGroup>
<ItemGroup>
<Image Include="Resources\gltf\WaterBottle\WaterBottle_baseColor.png">
Expand Down Expand Up @@ -104,6 +110,9 @@
<Image Include="Resources\gltf\WaterBottle_ORM\WaterBottle_specularGlossiness.png">
<Filter>Resources\WaterBottle_ORM</Filter>
</Image>
<Image Include="Resources\gltf\TextureTest\0.png">
<Filter>Resources\TextureTest</Filter>
</Image>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Helpers\TestUtils.h">
Expand Down
27 changes: 23 additions & 4 deletions glTF-Toolkit/src/GLTFTextureCompressionUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,32 @@ GLTFDocument GLTFTextureCompressionUtils::CompressTextureAsDDS(const IStreamRead

auto image = std::make_unique<DirectX::ScratchImage>(GLTFTextureLoadingUtils::LoadTexture(streamReader, doc, texture.id));

// Resize
// Resize up to a multiple of 4
auto metadata = image->GetMetadata();
if (maxTextureSize < metadata.width || maxTextureSize < metadata.height)
auto resizedWidth = metadata.width;
auto resizedHeight = metadata.height;

if (maxTextureSize < resizedWidth || maxTextureSize < resizedHeight)
{
// Scale
auto scaleFactor = static_cast<double>(maxTextureSize) / std::max(metadata.width, metadata.height);
auto resizedWidth = static_cast<size_t>(std::llround(metadata.width * scaleFactor));
auto resizedHeight = static_cast<size_t>(std::llround(metadata.height * scaleFactor));
resizedWidth = static_cast<size_t>(std::llround(metadata.width * scaleFactor));
resizedHeight = static_cast<size_t>(std::llround(metadata.height * scaleFactor));
}

if (resizedWidth % 4 != 0 || resizedHeight % 4 != 0)
{
static const std::function<size_t(size_t)> roundUpToMultipleOf4 = [](size_t input)
{
return input % 4 == 0 ? input : (input + 4) - (input % 4);
};

resizedWidth = roundUpToMultipleOf4(resizedWidth);
resizedHeight = roundUpToMultipleOf4(resizedHeight);
}

if (resizedWidth != metadata.width || resizedHeight != metadata.height)
{
auto resized = std::make_unique<DirectX::ScratchImage>();
if (FAILED(DirectX::Resize(image->GetImages(), image->GetImageCount(), image->GetMetadata(), resizedWidth, resizedHeight, DirectX::TEX_FILTER_DEFAULT, *resized)))
{
Expand Down

0 comments on commit 4a3f028

Please sign in to comment.