#include "Game/T6/Techset/TechsetCompilerT6.h" #include "Game/T6/T6.h" #include "SearchPath/MockSearchPath.h" #include "Techset/TechsetCommon.h" #include "Utils/TestMemoryManager.h" #include #include #include #include using namespace T6; using namespace std::string_literals; namespace { MaterialTechnique* GivenTechnique(const std::string& name, AssetCreationContext& context, MemoryManager& memory) { auto* technique = memory.Alloc(); technique->name = memory.Dup(name.c_str()); context.AddSubAsset(name, technique); return technique; } } // namespace TEST_CASE("TechsetCompilerT6", "[techset][t6][compiler]") { Zone zone("test", 0, GameId::T6, GamePlatform::PC); AssetCreatorCollection creators(zone); IgnoredAssetLookup ignoredAssets; AssetCreationContext context(zone, &creators, &ignoredAssets); MockSearchPath searchPath; TestMemoryManager memory; const auto sut = techset::CreateCompilerT6(memory, searchPath); SECTION("Sets correct worldVertFormat") { const auto [techsetName, expectedWorldVertFormat] = GENERATE(Catch::Generators::table({ {"default", MTL_WORLDVERT_TEX_1_NRM_1}, {"effect_zeqqz943", MTL_WORLDVERT_TEX_1_NRM_1}, {"lit_r0c0_t1c1n1", MTL_WORLDVERT_TEX_2_NRM_1}, {"lit_r0c0n0x0_b1c1n1s1v1", MTL_WORLDVERT_TEX_2_NRM_2}, {"lit_r0c0n0x0_b1c1n1s1v1_b2c2n2x2", MTL_WORLDVERT_TEX_3_NRM_3}, {"lit_sm_b0c0_b1c1_b2c2", MTL_WORLDVERT_TEX_3_NRM_1}, {"lit_sm_b0c0_b1c1n1x1_b2c2n2v2", MTL_WORLDVERT_TEX_3_NRM_2}, {"lit_sm_r0c0_b1c1_b2c2_b3c3", MTL_WORLDVERT_TEX_4_NRM_1}, {"lit_sm_r0c0n0_b1c1_b2c2n2v2_m3c3", MTL_WORLDVERT_TEX_4_NRM_2}, {"lit_sm_r0c0n0_b1c1n1s1", MTL_WORLDVERT_TEX_2_NRM_2}, {"lit_sm_r0c0n0s0_b1c1n1s1_b2c2n2", MTL_WORLDVERT_TEX_3_NRM_3}, {"lit_sm_r0c0n0x0_b1c1_b2c2n2s2", MTL_WORLDVERT_TEX_3_NRM_2}, {"lit_sm_r0c0n0x0_b1c1n1_b2c2n2s2v2", MTL_WORLDVERT_TEX_3_NRM_3}, {"lit_sm_r0c0n0x0_b1c1s1v1_m2c2_m3c3", MTL_WORLDVERT_TEX_4_NRM_1}, {"lit_sm_r0c0n0x0_b1c1v1_b2c2n2s2_m3c3", MTL_WORLDVERT_TEX_4_NRM_2}, {"lit_sm_r0c0s0_b1c1n1s1_m2c2", MTL_WORLDVERT_TEX_3_NRM_1}, {"lit_sm_r0c0x0_b1c1", MTL_WORLDVERT_TEX_2_NRM_1}, {"lit_sm_r0c0x0_b1c1n1s1_b2c2n2s2", MTL_WORLDVERT_TEX_3_NRM_2}, {"lit_sm_r0c0x0_m1c1_m2c2_m3c3", MTL_WORLDVERT_TEX_4_NRM_1}, {"lit_sm_t0c0n0_b1c1n1v1", MTL_WORLDVERT_TEX_2_NRM_2}, {"lit_sm_t0c0n0s0_b1c1n1_b2c2n2s2v2", MTL_WORLDVERT_TEX_3_NRM_3}, {"mc_lit_sm_r0c0d0_2213939z", MTL_WORLDVERT_TEX_1_NRM_1}, {"wpc_lit_sm_b0c0s0_3f3q946z", MTL_WORLDVERT_TEX_1_NRM_1}, {"wpc_lit_sm_r0c0n0s0o0_qj92q1f8", MTL_WORLDVERT_TEX_1_NRM_1}, {"wpc_sw4_3d_burning_embers_nuketown_74j6971w", MTL_WORLDVERT_TEX_1_NRM_1}, {"wpc_unlitdecalblend_add_j26wq580", MTL_WORLDVERT_TEX_1_NRM_1}, })); CAPTURE(techsetName); searchPath.AddFileData(techset::GetFileNameForTechsetName(techsetName), ""); const auto result = sut->CreateAsset(techsetName, context); REQUIRE(result.HasBeenSuccessful()); const auto* techset = static_cast(result.GetAssetInfo()->m_ptr); CHECK(techset->worldVertFormat == expectedWorldVertFormat); } SECTION("Can parse simple techset") { searchPath.AddFileData(techset::GetFileNameForTechsetName("simple"), R"TECHSET( "depth prepass": example_zprepass; "lit sun shadow": example_lit_sun_shadow; )TECHSET"); auto* exampleZPrepass = GivenTechnique("example_zprepass", context, memory); auto* exampleLitSunShadow = GivenTechnique("example_lit_sun_shadow", context, memory); const auto result = sut->CreateAsset("simple", context); REQUIRE(result.HasBeenSuccessful()); const auto* techset = static_cast(result.GetAssetInfo()->m_ptr); CHECK(techset->name == "simple"s); CHECK(techset->worldVertFormat == MTL_WORLDVERT_TEX_1_NRM_1); size_t techniqueCount = 0; for (auto* technique : techset->techniques) { if (technique) techniqueCount++; } CHECK(techniqueCount == 2); CHECK(techset->techniques[TECHNIQUE_DEPTH_PREPASS] == exampleZPrepass); CHECK(techset->techniques[TECHNIQUE_LIT_SUN_SHADOW] == exampleLitSunShadow); } SECTION("Can parse techset with same technique used multiple times") { searchPath.AddFileData(techset::GetFileNameForTechsetName("simple"), R"TECHSET( "depth prepass": "build shadowmap depth": example_zprepass; "lit": "lit sun": "lit sun shadow": example_lit_sun_shadow; )TECHSET"); auto* exampleZPrepass = GivenTechnique("example_zprepass", context, memory); auto* exampleLitSunShadow = GivenTechnique("example_lit_sun_shadow", context, memory); const auto result = sut->CreateAsset("simple", context); REQUIRE(result.HasBeenSuccessful()); const auto* techset = static_cast(result.GetAssetInfo()->m_ptr); CHECK(techset->name == "simple"s); CHECK(techset->worldVertFormat == MTL_WORLDVERT_TEX_1_NRM_1); size_t techniqueCount = 0; for (auto* technique : techset->techniques) { if (technique) techniqueCount++; } CHECK(techniqueCount == 5); CHECK(techset->techniques[TECHNIQUE_DEPTH_PREPASS] == exampleZPrepass); CHECK(techset->techniques[TECHNIQUE_BUILD_SHADOWMAP_DEPTH] == exampleZPrepass); CHECK(techset->techniques[TECHNIQUE_LIT] == exampleLitSunShadow); CHECK(techset->techniques[TECHNIQUE_LIT_SUN] == exampleLitSunShadow); CHECK(techset->techniques[TECHNIQUE_LIT_SUN_SHADOW] == exampleLitSunShadow); } }