mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-02-10 17:43:03 +00:00
feat: dump t5 techsets and techniques
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "Game/T5/GameAssetPoolT5.h"
|
||||
#include "Game/T5/Material/MaterialJsonDumperT5.h"
|
||||
#include "Game/T5/Techset/TechsetDumperT5.h"
|
||||
#include "Game/T5/XModel/XModelDumperT5.h"
|
||||
#include "Image/ImageDumperT5.h"
|
||||
#include "Localize/LocalizeDumperT5.h"
|
||||
@@ -28,7 +29,7 @@ bool ObjWriter::DumpZone(AssetDumpingContext& context) const
|
||||
// REGISTER_DUMPER(AssetDumperXAnimParts, m_xanim_parts)
|
||||
REGISTER_DUMPER(xmodel::DumperT5, m_xmodel)
|
||||
REGISTER_DUMPER(material::JsonDumperT5, m_material)
|
||||
// REGISTER_DUMPER(AssetDumperTechniqueSet, m_technique_set)
|
||||
REGISTER_DUMPER(techset::DumperT5, m_technique_set)
|
||||
REGISTER_DUMPER(image::DumperT5, m_image)
|
||||
// REGISTER_DUMPER(AssetDumperSndBank, m_sound_bank)
|
||||
// REGISTER_DUMPER(AssetDumperSndPatch, m_sound_patch)
|
||||
|
||||
339
src/ObjWriting/Game/T5/Techset/TechsetDumperT5.cpp
Normal file
339
src/ObjWriting/Game/T5/Techset/TechsetDumperT5.cpp
Normal file
@@ -0,0 +1,339 @@
|
||||
#include "TechsetDumperT5.h"
|
||||
|
||||
#include "Game/T5/Material/MaterialConstantZoneStateT5.h"
|
||||
#include "Game/T5/Techset/TechsetConstantsT5.h"
|
||||
#include "Shader/ShaderCommon.h"
|
||||
#include "Techset/CommonTechniqueDumper.h"
|
||||
#include "Techset/CommonTechsetDumper.h"
|
||||
#include "Techset/ShaderDumpingZoneState.h"
|
||||
#include "Techset/TechniqueDumpingZoneState.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <unordered_set>
|
||||
|
||||
using namespace T5;
|
||||
|
||||
namespace
|
||||
{
|
||||
void DumpPixelShader(const AssetDumpingContext& context, const MaterialPixelShader& pixelShader)
|
||||
{
|
||||
const auto shaderFile = context.OpenAssetFile(shader::GetFileNameForPixelShaderAssetName(pixelShader.name));
|
||||
|
||||
if (!shaderFile)
|
||||
return;
|
||||
|
||||
shaderFile->write(reinterpret_cast<char*>(pixelShader.prog.loadDef.program), pixelShader.prog.loadDef.programSize * sizeof(uint32_t));
|
||||
}
|
||||
|
||||
void DumpVertexShader(const AssetDumpingContext& context, const MaterialVertexShader& vertexShader)
|
||||
{
|
||||
const auto shaderFile = context.OpenAssetFile(shader::GetFileNameForVertexShaderAssetName(vertexShader.name));
|
||||
|
||||
if (!shaderFile)
|
||||
return;
|
||||
|
||||
shaderFile->write(reinterpret_cast<char*>(vertexShader.prog.loadDef.program), vertexShader.prog.loadDef.programSize * sizeof(uint32_t));
|
||||
}
|
||||
|
||||
void DumpShaders(AssetDumpingContext& context, const MaterialTechniqueSet& techset)
|
||||
{
|
||||
auto* shaderState = context.GetZoneAssetDumperState<techset::ShaderDumpingZoneState>();
|
||||
|
||||
for (const auto* technique : techset.techniques)
|
||||
{
|
||||
if (!technique || !shaderState->ShouldDumpTechnique(technique))
|
||||
continue;
|
||||
|
||||
for (auto passIndex = 0u; passIndex < technique->passCount; passIndex++)
|
||||
{
|
||||
const auto* pixelShader = technique->passArray[passIndex].pixelShader;
|
||||
if (pixelShader && shaderState->ShouldDumpPixelShader(pixelShader))
|
||||
DumpPixelShader(context, *pixelShader);
|
||||
|
||||
const auto* vertexShader = technique->passArray[passIndex].vertexShader;
|
||||
if (vertexShader && shaderState->ShouldDumpVertexShader(vertexShader))
|
||||
DumpVertexShader(context, *vertexShader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
techset::CommonVertexDeclaration ConvertToCommonVertexDeclaration(const MaterialVertexDeclaration* vertexDecl)
|
||||
{
|
||||
std::vector<techset::CommonStreamRouting> commonRouting;
|
||||
|
||||
if (vertexDecl)
|
||||
{
|
||||
const auto streamCount = std::min(static_cast<size_t>(vertexDecl->streamCount), std::extent_v<decltype(MaterialVertexStreamRouting::data)>);
|
||||
for (auto streamIndex = 0u; streamIndex < streamCount; streamIndex++)
|
||||
{
|
||||
const auto& routing = vertexDecl->routing.data[streamIndex];
|
||||
commonRouting.emplace_back(techset::CommonStreamRouting{
|
||||
.m_source = static_cast<techset::CommonStreamSource>(routing.source),
|
||||
.m_destination = static_cast<techset::CommonStreamDestination>(routing.dest),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return techset::CommonVertexDeclaration{
|
||||
.m_routing = std::move(commonRouting),
|
||||
};
|
||||
}
|
||||
|
||||
techset::CommonShaderArg ConvertToCommonArg(const MaterialShaderArgument& arg)
|
||||
{
|
||||
switch (arg.type)
|
||||
{
|
||||
case MTL_ARG_CODE_VERTEX_CONST:
|
||||
case MTL_ARG_CODE_PIXEL_CONST:
|
||||
return techset::CommonShaderArg{
|
||||
.m_type = techset::CommonShaderArgType::CODE_CONST,
|
||||
.m_destination = {.dx9 =
|
||||
{
|
||||
.m_destination_register = arg.dest,
|
||||
}},
|
||||
.m_value = {
|
||||
.code_const_source = static_cast<techset::CommonCodeConstSource>(arg.u.codeConst.index),
|
||||
}
|
||||
};
|
||||
|
||||
case MTL_ARG_MATERIAL_VERTEX_CONST:
|
||||
case MTL_ARG_MATERIAL_PIXEL_CONST:
|
||||
return techset::CommonShaderArg{
|
||||
.m_type = techset::CommonShaderArgType::MATERIAL_CONST,
|
||||
.m_destination = {.dx9 =
|
||||
{
|
||||
.m_destination_register = arg.dest,
|
||||
}},
|
||||
.m_value = {
|
||||
.name_hash = arg.u.nameHash,
|
||||
}
|
||||
};
|
||||
|
||||
case MTL_ARG_CODE_PIXEL_SAMPLER:
|
||||
return techset::CommonShaderArg{
|
||||
.m_type = techset::CommonShaderArgType::CODE_SAMPLER,
|
||||
.m_destination = {.dx9 =
|
||||
{
|
||||
.m_destination_register = arg.dest,
|
||||
}},
|
||||
.m_value = {
|
||||
.code_sampler_source = static_cast<techset::CommonCodeSamplerSource>(arg.u.codeSampler),
|
||||
}
|
||||
};
|
||||
|
||||
case MTL_ARG_MATERIAL_PIXEL_SAMPLER:
|
||||
return techset::CommonShaderArg{
|
||||
.m_type = techset::CommonShaderArgType::MATERIAL_SAMPLER,
|
||||
.m_destination = {.dx9 =
|
||||
{
|
||||
.m_destination_register = arg.dest,
|
||||
}},
|
||||
.m_value = {
|
||||
.name_hash = arg.u.nameHash,
|
||||
}
|
||||
};
|
||||
|
||||
default:
|
||||
case MTL_ARG_LITERAL_VERTEX_CONST:
|
||||
case MTL_ARG_LITERAL_PIXEL_CONST:
|
||||
if (arg.u.literalConst)
|
||||
{
|
||||
return techset::CommonShaderArg{
|
||||
.m_type = techset::CommonShaderArgType::LITERAL_CONST,
|
||||
.m_destination = {.dx9 =
|
||||
{
|
||||
.m_destination_register = arg.dest,
|
||||
}},
|
||||
.m_value = {
|
||||
.literal_value =
|
||||
{
|
||||
(*arg.u.literalConst)[0],
|
||||
(*arg.u.literalConst)[1],
|
||||
(*arg.u.literalConst)[2],
|
||||
(*arg.u.literalConst)[3],
|
||||
}, }
|
||||
};
|
||||
}
|
||||
|
||||
return techset::CommonShaderArg{
|
||||
.m_type = techset::CommonShaderArgType::LITERAL_CONST,
|
||||
.m_destination = {.dx9 =
|
||||
{
|
||||
.m_destination_register = arg.dest,
|
||||
}},
|
||||
.m_value = {},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
techset::CommonTechniqueShader ConvertToCommonShader(const MaterialPass& pass, const MaterialVertexShader* vertexShader)
|
||||
{
|
||||
techset::CommonTechniqueShader result{};
|
||||
if (!vertexShader)
|
||||
return result;
|
||||
|
||||
if (vertexShader->name)
|
||||
result.m_name = vertexShader->name;
|
||||
|
||||
if (vertexShader->prog.loadDef.program)
|
||||
{
|
||||
result.m_shader_bin = vertexShader->prog.loadDef.program;
|
||||
result.m_shader_bin_size = vertexShader->prog.loadDef.programSize * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
if (pass.args)
|
||||
{
|
||||
const size_t totalArgCount = pass.perPrimArgCount + pass.perObjArgCount + pass.stableArgCount;
|
||||
for (auto argIndex = 0uz; argIndex < totalArgCount; argIndex++)
|
||||
{
|
||||
const auto& arg = pass.args[argIndex];
|
||||
|
||||
switch (arg.type)
|
||||
{
|
||||
case MTL_ARG_CODE_VERTEX_CONST:
|
||||
case MTL_ARG_MATERIAL_VERTEX_CONST:
|
||||
case MTL_ARG_LITERAL_VERTEX_CONST:
|
||||
result.m_args.emplace_back(ConvertToCommonArg(arg));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
techset::CommonTechniqueShader ConvertToCommonShader(const MaterialPass& pass, const MaterialPixelShader* pixelShader)
|
||||
{
|
||||
techset::CommonTechniqueShader result{};
|
||||
if (!pixelShader)
|
||||
return result;
|
||||
|
||||
if (pixelShader->name)
|
||||
result.m_name = pixelShader->name;
|
||||
|
||||
if (pixelShader->prog.loadDef.program)
|
||||
{
|
||||
result.m_shader_bin = pixelShader->prog.loadDef.program;
|
||||
result.m_shader_bin_size = pixelShader->prog.loadDef.programSize * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
if (pass.args)
|
||||
{
|
||||
const size_t totalArgCount = pass.perPrimArgCount + pass.perObjArgCount + pass.stableArgCount;
|
||||
for (auto argIndex = 0uz; argIndex < totalArgCount; argIndex++)
|
||||
{
|
||||
const auto& arg = pass.args[argIndex];
|
||||
|
||||
switch (arg.type)
|
||||
{
|
||||
case MTL_ARG_CODE_PIXEL_CONST:
|
||||
case MTL_ARG_CODE_PIXEL_SAMPLER:
|
||||
case MTL_ARG_MATERIAL_PIXEL_CONST:
|
||||
case MTL_ARG_MATERIAL_PIXEL_SAMPLER:
|
||||
case MTL_ARG_LITERAL_PIXEL_CONST:
|
||||
result.m_args.emplace_back(ConvertToCommonArg(arg));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
techset::CommonTechnique ConvertToCommonTechnique(const MaterialTechnique& technique)
|
||||
{
|
||||
std::vector<techset::CommonPass> passes;
|
||||
|
||||
for (auto passIndex = 0u; passIndex < technique.passCount; passIndex++)
|
||||
{
|
||||
const auto& pass = technique.passArray[passIndex];
|
||||
|
||||
passes.emplace_back(techset::CommonPass{
|
||||
.m_sampler_flags = pass.customSamplerFlags,
|
||||
.m_dx_version = techset::DxVersion::DX9,
|
||||
.m_vertex_shader = ConvertToCommonShader(pass, pass.vertexShader),
|
||||
.m_pixel_shader = ConvertToCommonShader(pass, pass.pixelShader),
|
||||
.m_vertex_declaration = ConvertToCommonVertexDeclaration(pass.vertexDecl),
|
||||
});
|
||||
}
|
||||
|
||||
return techset::CommonTechnique{
|
||||
.m_name = technique.name ? technique.name : std::string(),
|
||||
.m_flags = technique.flags,
|
||||
.m_passes = std::move(passes),
|
||||
};
|
||||
}
|
||||
|
||||
void DumpTechniques(AssetDumpingContext& context, const MaterialTechniqueSet& techset)
|
||||
{
|
||||
static techset::CommonCodeSourceInfos codeSourceInfos(commonCodeConstSources,
|
||||
std::extent_v<decltype(commonCodeConstSources)>,
|
||||
commonCodeSamplerSources,
|
||||
std::extent_v<decltype(commonCodeSamplerSources)>);
|
||||
static techset::CommonStreamRoutingInfos routingInfos(
|
||||
streamRoutingSources, std::extent_v<decltype(streamRoutingSources)>, streamRoutingDestinations, std::extent_v<decltype(streamRoutingDestinations)>);
|
||||
|
||||
auto* techniqueState = context.GetZoneAssetDumperState<techset::TechniqueDumpingZoneState>();
|
||||
const auto* materialConstantState = context.GetZoneAssetDumperState<MaterialConstantZoneState>();
|
||||
for (const auto* technique : techset.techniques)
|
||||
{
|
||||
if (technique && techniqueState->ShouldDumpTechnique(technique))
|
||||
{
|
||||
const auto commonTechnique = ConvertToCommonTechnique(*technique);
|
||||
|
||||
techset::DumpCommonTechnique(context, commonTechnique, codeSourceInfos, routingInfos, *materialConstantState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
techset::CommonTechset ConvertToCommonTechset(const MaterialTechniqueSet& techset)
|
||||
{
|
||||
std::vector<std::string> techniqueNames(std::extent_v<decltype(techniqueTypeNames)>);
|
||||
|
||||
for (auto techniqueIndex = 0u; techniqueIndex < std::extent_v<decltype(techniqueTypeNames)>; techniqueIndex++)
|
||||
{
|
||||
const auto* technique = techset.techniques[techniqueIndex];
|
||||
if (technique && technique->name)
|
||||
techniqueNames[techniqueIndex] = technique->name;
|
||||
}
|
||||
|
||||
return techset::CommonTechset{
|
||||
.m_name = techset.name,
|
||||
.m_technique_names = std::move(techniqueNames),
|
||||
};
|
||||
}
|
||||
|
||||
void DumpTechset(const AssetDumpingContext& context, const MaterialTechniqueSet& techset)
|
||||
{
|
||||
static techset::CommonTechniqueTypeNames commonNames(techniqueTypeNames, std::extent_v<decltype(techniqueTypeNames)>);
|
||||
const auto commonTechset = ConvertToCommonTechset(techset);
|
||||
|
||||
techset::DumpCommonTechset(commonNames, context, commonTechset);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace techset
|
||||
{
|
||||
DumperT5::DumperT5(const AssetPool<AssetTechniqueSet::Type>& pool)
|
||||
: AbstractAssetDumper(pool)
|
||||
{
|
||||
}
|
||||
|
||||
void DumperT5::Dump(AssetDumpingContext& context)
|
||||
{
|
||||
context.GetZoneAssetDumperState<MaterialConstantZoneState>()->EnsureInitialized();
|
||||
AbstractAssetDumper::Dump(context);
|
||||
}
|
||||
|
||||
void DumperT5::DumpAsset(AssetDumpingContext& context, const XAssetInfo<AssetTechniqueSet::Type>& asset)
|
||||
{
|
||||
const auto* techniqueSet = asset.Asset();
|
||||
DumpTechset(context, *techniqueSet);
|
||||
DumpTechniques(context, *techniqueSet);
|
||||
DumpShaders(context, *techniqueSet);
|
||||
}
|
||||
} // namespace techset
|
||||
18
src/ObjWriting/Game/T5/Techset/TechsetDumperT5.h
Normal file
18
src/ObjWriting/Game/T5/Techset/TechsetDumperT5.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "Dumping/AbstractAssetDumper.h"
|
||||
#include "Game/T5/T5.h"
|
||||
|
||||
namespace techset
|
||||
{
|
||||
class DumperT5 final : public AbstractAssetDumper<T5::AssetTechniqueSet>
|
||||
{
|
||||
public:
|
||||
explicit DumperT5(const AssetPool<T5::AssetTechniqueSet::Type>& pool);
|
||||
|
||||
void Dump(AssetDumpingContext& context) override;
|
||||
|
||||
protected:
|
||||
void DumpAsset(AssetDumpingContext& context, const XAssetInfo<T5::AssetTechniqueSet::Type>& asset) override;
|
||||
};
|
||||
} // namespace techset
|
||||
Reference in New Issue
Block a user