mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-07-19 14:30:37 +00:00
fix: IW3 ensure loadForRenderer is set for shaders (#907)
* fix: IW3 restore renderer loading for disk shaders * fix: IW3 ensure `loadForRenderer` is set for shaders * fix: use modtools linker logic for iw3 loadForRenderer shader values --------- Co-authored-by: Jan Laupetin <[email protected]>
This commit is contained in:
@@ -69,6 +69,28 @@ namespace
|
||||
return static_cast<MaterialWorldVertexFormat>(0);
|
||||
}
|
||||
|
||||
#if defined(FEATURE_IW3)
|
||||
uint16_t GetLoadForRenderer(const std::string& techniqueSetName)
|
||||
{
|
||||
if (techniqueSetName.starts_with("sm2/"))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ApplyLoadForRendererToTechnique(const MaterialTechnique& technique, const uint16_t loadForRenderer)
|
||||
{
|
||||
for (auto passIndex = 0u; passIndex < technique.passCount; passIndex++)
|
||||
{
|
||||
auto* vertexShader = technique.passArray[passIndex].vertexShader;
|
||||
if (vertexShader)
|
||||
vertexShader->prog.loadDef.loadForRenderer = std::max(vertexShader->prog.loadDef.loadForRenderer, loadForRenderer);
|
||||
auto* pixelShader = technique.passArray[passIndex].pixelShader;
|
||||
if (pixelShader)
|
||||
pixelShader->prog.loadDef.loadForRenderer = std::max(pixelShader->prog.loadDef.loadForRenderer, loadForRenderer);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FEATURE_T6)
|
||||
MaterialType GetMaterialType(const std::string& name)
|
||||
{
|
||||
@@ -116,6 +138,9 @@ namespace
|
||||
return failure ? AssetCreationResult::Failure() : AssetCreationResult::NoAction();
|
||||
|
||||
auto* techset = ConvertTechniqueSet(*commonTechset, m_memory);
|
||||
#if defined(FEATURE_IW3)
|
||||
const auto loadForRenderer = GetLoadForRenderer(assetName);
|
||||
#endif
|
||||
#if defined(FEATURE_T6)
|
||||
const auto materialType = GetMaterialType(assetName);
|
||||
#endif
|
||||
@@ -132,6 +157,12 @@ namespace
|
||||
|
||||
techset->techniques[techniqueIndex] = technique->Asset();
|
||||
|
||||
#if defined(FEATURE_IW3)
|
||||
// IW3 supports both sm2 and sm3.
|
||||
// The shader's loadForRenderer property is set to 0 for sm2 and 1 for sm3.
|
||||
// Which shader model a techset is for is entirely determined by its name according to modtools.
|
||||
ApplyLoadForRendererToTechnique(*techset->techniques[techniqueIndex], loadForRenderer);
|
||||
#endif
|
||||
#if defined(FEATURE_T6)
|
||||
// Another techset may override this for the technique
|
||||
// but the game determines the material type by techset name.
|
||||
|
||||
@@ -19,6 +19,9 @@ namespace
|
||||
{
|
||||
auto* technique = memory.Alloc<MaterialTechnique>();
|
||||
technique->name = memory.Dup(name.c_str());
|
||||
technique->passCount = 1;
|
||||
technique->passArray[0].vertexShader = memory.Alloc<MaterialVertexShader>();
|
||||
technique->passArray[0].pixelShader = memory.Alloc<MaterialPixelShader>();
|
||||
|
||||
context.AddSubAsset<SubAssetTechnique>(name, technique);
|
||||
|
||||
@@ -79,7 +82,13 @@ TEST_CASE("TechsetCompilerIW3", "[techset][iw3][compiler]")
|
||||
|
||||
SECTION("Can parse simple techset")
|
||||
{
|
||||
searchPath.AddFileData(techset::GetFileNameForTechsetName("simple"), R"TECHSET(
|
||||
const auto [techsetName, expectedLoadForRendererValue] = GENERATE(Catch::Generators::table<std::string, uint16_t>({
|
||||
{"simple", 1},
|
||||
{"sm2/simple", 0},
|
||||
}));
|
||||
CAPTURE(techsetName);
|
||||
|
||||
searchPath.AddFileData(techset::GetFileNameForTechsetName(techsetName), R"TECHSET(
|
||||
"depth prepass":
|
||||
example_zprepass;
|
||||
|
||||
@@ -90,11 +99,11 @@ TEST_CASE("TechsetCompilerIW3", "[techset][iw3][compiler]")
|
||||
auto* exampleZPrepass = GivenTechnique("example_zprepass", context, memory);
|
||||
auto* exampleLit = GivenTechnique("example_lit_spot", context, memory);
|
||||
|
||||
const auto result = sut->CreateAsset("simple", context);
|
||||
const auto result = sut->CreateAsset(techsetName, context);
|
||||
REQUIRE(result.HasBeenSuccessful());
|
||||
|
||||
const auto* techset = static_cast<MaterialTechniqueSet*>(result.GetAssetInfo()->m_ptr);
|
||||
CHECK(techset->name == "simple"s);
|
||||
CHECK(techset->name == techsetName);
|
||||
CHECK(techset->worldVertFormat == MTL_WORLDVERT_TEX_1_NRM_1);
|
||||
|
||||
size_t techniqueCount = 0;
|
||||
@@ -107,6 +116,10 @@ TEST_CASE("TechsetCompilerIW3", "[techset][iw3][compiler]")
|
||||
CHECK(techniqueCount == 2);
|
||||
CHECK(techset->techniques[TECHNIQUE_DEPTH_PREPASS] == exampleZPrepass);
|
||||
CHECK(techset->techniques[TECHNIQUE_LIT_SPOT] == exampleLit);
|
||||
|
||||
// Make sure IW3 techset postprocessing sets correct values for loadForRenderer
|
||||
CHECK(exampleZPrepass->passArray[0].vertexShader->prog.loadDef.loadForRenderer == expectedLoadForRendererValue);
|
||||
CHECK(exampleZPrepass->passArray[0].pixelShader->prog.loadDef.loadForRenderer == expectedLoadForRendererValue);
|
||||
}
|
||||
|
||||
SECTION("Can parse techset with same technique used multiple times")
|
||||
|
||||
Reference in New Issue
Block a user