mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-11-09 17:51:58 +00:00
fix: handle embedded cubemap face order correctly (#996)
* fix: handle embedded cubemap face order correctly * chore: do not treat cubemaps as separate logic when not necessary * chore: make sure face major image data is the default and chosen for any game other than qos * chore: make new tests use no namespace --------- Co-authored-by: Jan Laupetin <[email protected]>
This commit is contained in:
1 parent
63e6d57b9c
commit
cc71ec7387
10 files changed
+281
-21
No files matched your search
@@ -0,0 +1,92 @@
|
||||
#include "Image/DdsLoader.h"
|
||||
#include "Image/DdsTypes.h"
|
||||
#include "Image/DdsWriter.h"
|
||||
#include "Image/Texture.h"
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace image;
|
||||
|
||||
namespace
|
||||
{
|
||||
void FillCube(TextureCube& texture)
|
||||
{
|
||||
for (auto face = 0; face < texture.GetFaceCount(); face++)
|
||||
{
|
||||
for (auto mip = 0; mip < texture.GetMipMapCount(); mip++)
|
||||
{
|
||||
const auto value = static_cast<unsigned char>(face * 16 + mip + 1);
|
||||
std::memset(texture.GetBufferForMipLevel(mip, face), value, texture.GetSizeOfMipLevel(mip));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<uint8_t> GetFaceMajorData(const TextureCube& texture)
|
||||
{
|
||||
std::vector<uint8_t> data;
|
||||
for (auto face = 0; face < texture.GetFaceCount(); face++)
|
||||
{
|
||||
for (auto mip = 0; mip < texture.GetMipMapCount(); mip++)
|
||||
{
|
||||
const auto* buffer = texture.GetBufferForMipLevel(mip, face);
|
||||
const auto mipSize = texture.GetSizeOfMipLevel(mip);
|
||||
data.insert(data.end(), buffer, buffer + mipSize);
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void RequireEqualCubeTextures(const TextureCube& expected, const Texture& actual)
|
||||
{
|
||||
REQUIRE(actual.GetTextureType() == TextureType::T_CUBE);
|
||||
REQUIRE(actual.GetMipMapCount() == expected.GetMipMapCount());
|
||||
|
||||
for (auto face = 0; face < expected.GetFaceCount(); face++)
|
||||
{
|
||||
for (auto mip = 0; mip < expected.GetMipMapCount(); mip++)
|
||||
{
|
||||
const auto mipSize = expected.GetSizeOfMipLevel(mip);
|
||||
REQUIRE(std::memcmp(actual.GetBufferForMipLevel(mip, face), expected.GetBufferForMipLevel(mip, face), mipSize) == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("DdsWriter stores cubemap mip chains face-major", "[image][dds]")
|
||||
{
|
||||
TextureCube source(&format::A8, 8, 8, true);
|
||||
source.Allocate();
|
||||
FillCube(source);
|
||||
|
||||
std::stringstream stream(std::ios::in | std::ios::out | std::ios::binary);
|
||||
DdsWriter writer;
|
||||
writer.DumpImage(stream, &source);
|
||||
|
||||
const auto data = stream.str();
|
||||
const auto expectedData = GetFaceMajorData(source);
|
||||
constexpr auto dataOffset = sizeof(uint32_t) + sizeof(DDS_HEADER);
|
||||
|
||||
REQUIRE(data.size() == dataOffset + expectedData.size());
|
||||
REQUIRE(std::memcmp(data.data() + dataOffset, expectedData.data(), expectedData.size()) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("DdsLoader reads face-major cubemap mip chains", "[image][dds]")
|
||||
{
|
||||
TextureCube source(&format::A8, 8, 8, true);
|
||||
source.Allocate();
|
||||
FillCube(source);
|
||||
|
||||
std::stringstream stream(std::ios::in | std::ios::out | std::ios::binary);
|
||||
DdsWriter writer;
|
||||
writer.DumpImage(stream, &source);
|
||||
stream.seekg(0);
|
||||
|
||||
const auto loaded = LoadDds(stream);
|
||||
REQUIRE(loaded);
|
||||
RequireEqualCubeTextures(source, *loaded);
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
#include "Image/Dx9TextureLoader.h"
|
||||
#include "Image/Texture.h"
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
using namespace image;
|
||||
|
||||
namespace
|
||||
{
|
||||
void FillCube(TextureCube& texture)
|
||||
{
|
||||
for (auto face = 0; face < texture.GetFaceCount(); face++)
|
||||
{
|
||||
for (auto mip = 0; mip < texture.GetMipMapCount(); mip++)
|
||||
{
|
||||
const auto value = static_cast<unsigned char>(face * 16 + mip + 1);
|
||||
std::memset(texture.GetBufferForMipLevel(mip, face), value, texture.GetSizeOfMipLevel(mip));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<uint8_t> GetFaceMajorData(const TextureCube& texture)
|
||||
{
|
||||
std::vector<uint8_t> data;
|
||||
for (auto face = 0; face < texture.GetFaceCount(); face++)
|
||||
{
|
||||
for (auto mip = 0; mip < texture.GetMipMapCount(); mip++)
|
||||
{
|
||||
const auto* buffer = texture.GetBufferForMipLevel(mip, face);
|
||||
const auto mipSize = texture.GetSizeOfMipLevel(mip);
|
||||
data.insert(data.end(), buffer, buffer + mipSize);
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void RequireEqualCubeTextures(const TextureCube& expected, const Texture& actual)
|
||||
{
|
||||
REQUIRE(actual.GetTextureType() == TextureType::T_CUBE);
|
||||
REQUIRE(actual.GetMipMapCount() == expected.GetMipMapCount());
|
||||
|
||||
for (auto face = 0; face < expected.GetFaceCount(); face++)
|
||||
{
|
||||
for (auto mip = 0; mip < expected.GetMipMapCount(); mip++)
|
||||
{
|
||||
const auto mipSize = expected.GetSizeOfMipLevel(mip);
|
||||
REQUIRE(std::memcmp(actual.GetBufferForMipLevel(mip, face), expected.GetBufferForMipLevel(mip, face), mipSize) == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("Dx9TextureLoader reads face-major cubemap mip chains", "[image][dx9]")
|
||||
{
|
||||
TextureCube source(&format::A8, 8, 8, true);
|
||||
source.Allocate();
|
||||
FillCube(source);
|
||||
|
||||
const auto data = GetFaceMajorData(source);
|
||||
Dx9TextureLoader loader;
|
||||
const auto loaded = loader.Format(source.GetFormat()->GetD3DFormat())
|
||||
.Type(TextureType::T_CUBE)
|
||||
.HasMipMaps(true)
|
||||
.CubeMapOrder(Dx9TextureLoader::CubeMapDataOrder::FaceMajor)
|
||||
.Width(source.GetWidth())
|
||||
.Height(source.GetHeight())
|
||||
.LoadTexture(data.data());
|
||||
|
||||
REQUIRE(loaded);
|
||||
RequireEqualCubeTextures(source, *loaded);
|
||||
}
|
||||
Reference in new issue
Block a user