2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2025-07-03 09:41:50 +00:00

feat: dump and load T5 materials

This commit is contained in:
Jan
2025-07-01 21:09:02 +01:00
parent fda91b84bd
commit c57ea0d2f2
18 changed files with 952 additions and 35 deletions

View File

@ -11,6 +11,21 @@ namespace T5
static int Com_HashString(const char* str);
static int Com_HashString(const char* str, int len);
static constexpr uint32_t R_HashString(const char* str, uint32_t hash)
{
for (const auto* pos = str; *pos; pos++)
{
hash = 33 * hash ^ (*pos | 0x20);
}
return hash;
}
static constexpr uint32_t R_HashString(const char* string)
{
return R_HashString(string, 0u);
}
static PackedTexCoords Vec2PackTexCoords(const float (&in)[2]);
static PackedUnitVec Vec3PackUnitVec(const float (&in)[3]);
static GfxColor Vec4PackGfxColor(const float (&in)[4]);

View File

@ -739,14 +739,30 @@ namespace T5
gcc_align32(8) uint64_t packed;
};
enum MaterialGameFlags
{
MTL_GAMEFLAG_1 = 0x1,
MTL_GAMEFLAG_2 = 0x2,
MTL_GAMEFLAG_4 = 0x4,
MTL_GAMEFLAG_8 = 0x8,
MTL_GAMEFLAG_10 = 0x10,
MTL_GAMEFLAG_20 = 0x20,
// Probably, seems to be this in T5
MTL_GAMEFLAG_CASTS_SHADOW = 0x40,
MTL_GAMEFLAG_80 = 0x80,
MTL_GAMEFLAG_100 = 0x100,
MTL_GAMEFLAG_200 = 0x200,
};
struct MaterialInfo
{
const char* name;
unsigned int gameFlags;
char pad;
char sortKey;
char textureAtlasRowCount;
char textureAtlasColumnCount;
unsigned char sortKey;
unsigned char textureAtlasRowCount;
unsigned char textureAtlasColumnCount;
GfxDrawSurf drawSurf;
unsigned int surfaceTypeBits;
unsigned int layeredSurfaceTypes;
@ -787,12 +803,45 @@ namespace T5
water_t* water;
};
enum TextureFilter
{
TEXTURE_FILTER_DISABLED = 0x0,
TEXTURE_FILTER_NEAREST = 0x1,
TEXTURE_FILTER_LINEAR = 0x2,
TEXTURE_FILTER_ANISO2X = 0x3,
TEXTURE_FILTER_ANISO4X = 0x4,
TEXTURE_FILTER_COUNT
};
enum SamplerStateBitsMipMap_e
{
SAMPLER_MIPMAP_ENUM_DISABLED,
SAMPLER_MIPMAP_ENUM_NEAREST,
SAMPLER_MIPMAP_ENUM_LINEAR,
SAMPLER_MIPMAP_ENUM_COUNT
};
struct MaterialTextureDefSamplerState
{
unsigned char filter : 3;
unsigned char mipMap : 2;
unsigned char clampU : 1;
unsigned char clampV : 1;
unsigned char clampW : 1;
};
#ifndef __zonecodegenerator
static_assert(sizeof(MaterialTextureDefSamplerState) == 1u);
#endif
struct MaterialTextureDef
{
unsigned int nameHash;
char nameStart;
char nameEnd;
char samplerState;
MaterialTextureDefSamplerState samplerState;
unsigned char semantic; // TextureSemantic
char isMatureContent;
char pad[3];
@ -803,7 +852,96 @@ namespace T5
{
unsigned int nameHash;
char name[12];
float literal[4];
vec4_t literal;
};
enum GfxBlend : unsigned int
{
GFXS_BLEND_DISABLED = 0x0,
GFXS_BLEND_ZERO = 0x1,
GFXS_BLEND_ONE = 0x2,
GFXS_BLEND_SRCCOLOR = 0x3,
GFXS_BLEND_INVSRCCOLOR = 0x4,
GFXS_BLEND_SRCALPHA = 0x5,
GFXS_BLEND_INVSRCALPHA = 0x6,
GFXS_BLEND_DESTALPHA = 0x7,
GFXS_BLEND_INVDESTALPHA = 0x8,
GFXS_BLEND_DESTCOLOR = 0x9,
GFXS_BLEND_INVDESTCOLOR = 0xA,
GFXS_BLEND_MASK = 0xF,
};
enum GfxBlendOp : unsigned int
{
GFXS_BLENDOP_DISABLED = 0x0,
GFXS_BLENDOP_ADD = 0x1,
GFXS_BLENDOP_SUBTRACT = 0x2,
GFXS_BLENDOP_REVSUBTRACT = 0x3,
GFXS_BLENDOP_MIN = 0x4,
GFXS_BLENDOP_MAX = 0x5,
GFXS_BLENDOP_MASK = 0x7,
};
enum GfxAlphaTest_e
{
GFXS_ALPHA_TEST_GT_0 = 1,
GFXS_ALPHA_TEST_GE_255 = 2,
GFXS_ALPHA_TEST_GE_128 = 3,
GFXS_ALPHA_TEST_COUNT
};
enum GfxCullFace_e
{
GFXS_CULL_NONE = 1,
GFXS_CULL_BACK = 2,
GFXS_CULL_FRONT = 3,
};
enum GfxDepthTest_e
{
GFXS_DEPTHTEST_ALWAYS = 0,
GFXS_DEPTHTEST_LESS = 1,
GFXS_DEPTHTEST_EQUAL = 2,
GFXS_DEPTHTEST_LESSEQUAL = 3
};
enum GfxPolygonOffset_e
{
GFXS_POLYGON_OFFSET_0 = 0,
GFXS_POLYGON_OFFSET_1 = 1,
GFXS_POLYGON_OFFSET_2 = 2,
GFXS_POLYGON_OFFSET_SHADOWMAP = 3
};
enum GfxStencilOp : unsigned int
{
GFXS_STENCILOP_KEEP = 0x0,
GFXS_STENCILOP_ZERO = 0x1,
GFXS_STENCILOP_REPLACE = 0x2,
GFXS_STENCILOP_INCRSAT = 0x3,
GFXS_STENCILOP_DECRSAT = 0x4,
GFXS_STENCILOP_INVERT = 0x5,
GFXS_STENCILOP_INCR = 0x6,
GFXS_STENCILOP_DECR = 0x7,
GFXS_STENCILOP_COUNT,
GFXS_STENCILOP_MASK = 0x7
};
enum GfxStencilFunc : unsigned int
{
GFXS_STENCILFUNC_NEVER = 0x0,
GFXS_STENCILFUNC_LESS = 0x1,
GFXS_STENCILFUNC_EQUAL = 0x2,
GFXS_STENCILFUNC_LESSEQUAL = 0x3,
GFXS_STENCILFUNC_GREATER = 0x4,
GFXS_STENCILFUNC_NOTEQUAL = 0x5,
GFXS_STENCILFUNC_GREATEREQUAL = 0x6,
GFXS_STENCILFUNC_ALWAYS = 0x7,
GFXS_STENCILFUNC_COUNT,
GFXS_STENCILFUNC_MASK = 0x7
};
enum GfxStateBitsEnum : unsigned int
@ -868,9 +1006,64 @@ namespace T5
GFXS1_STENCILOP_FRONTBACK_MASK = 0x1FF1FF00,
};
struct GfxStateBitsLoadBitsStructured
{
// Byte 0
unsigned int srcBlendRgb : 4; // 0-3
unsigned int dstBlendRgb : 4; // 4-7
unsigned int blendOpRgb : 3; // 8-10
unsigned int alphaTestDisabled : 1; // 11
unsigned int alphaTest : 2; // 12-13
unsigned int cullFace : 2; // 14-15
unsigned int srcBlendAlpha : 4; // 16-19
unsigned int dstBlendAlpha : 4; // 20-23
unsigned int blendOpAlpha : 3; // 24-26
unsigned int colorWriteRgb : 1; // 27
unsigned int colorWriteAlpha : 1; // 28
unsigned int unused0 : 2; // 29-30
unsigned int polymodeLine : 1; // 31
// Byte 1
unsigned int depthWrite : 1; // 0
unsigned int depthTestDisabled : 1; // 1
unsigned int depthTest : 2; // 2-3
unsigned int polygonOffset : 2; // 4-5
unsigned int stencilFrontEnabled : 1; // 6
unsigned int stencilBackEnabled : 1; // 7
unsigned int stencilFrontPass : 3; // 8-10
unsigned int stencilFrontFail : 3; // 11-13
unsigned int stencilFrontZFail : 3; // 14-16
unsigned int stencilFrontFunc : 3; // 17-19
unsigned int stencilBackPass : 3; // 20-22
unsigned int stencilBackFail : 3; // 23-25
unsigned int stencilBackZFail : 3; // 26-28
unsigned int stencilBackFunc : 3; // 29-31
};
union GfxStateBitsLoadBits
{
unsigned int raw[2];
GfxStateBitsLoadBitsStructured structured;
};
#ifndef __zonecodegenerator
static_assert(sizeof(GfxStateBitsLoadBits) == 8);
static_assert(sizeof(GfxStateBitsLoadBitsStructured) == 8);
#endif
struct GfxStateBits
{
unsigned int loadBits[2];
GfxStateBitsLoadBits loadBits;
};
enum GfxCameraRegionType
{
CAMERA_REGION_LIT = 0x0,
CAMERA_REGION_DECAL = 0x1,
CAMERA_REGION_EMISSIVE = 0x2,
CAMERA_REGION_COUNT,
CAMERA_REGION_NONE = CAMERA_REGION_COUNT,
};
struct Material
@ -880,8 +1073,8 @@ namespace T5
unsigned char textureCount;
unsigned char constantCount;
unsigned char stateBitsCount;
char stateFlags;
char cameraRegion;
unsigned char stateFlags;
unsigned char cameraRegion;
unsigned char maxStreamedMips;
MaterialTechniqueSet* techniqueSet;
MaterialTextureDef* textureTable;

View File

@ -700,6 +700,8 @@ namespace T6
MTL_GAMEFLAG_400 = 0x400,
MTL_GAMEFLAG_800 = 0x800,
MTL_GAMEFLAG_1000 = 0x1000,
MTL_GAMEFLAG_2000 = 0x2000,
MTL_GAMEFLAG_4000 = 0x4000,
};
struct type_align32(8) MaterialInfo

View File

@ -1,4 +1,4 @@
#options GAME (IW3, IW4, IW5, T6)
#options GAME (IW3, IW4, IW5, T5, T6)
#filename "Game/" + GAME + "/Material/JsonMaterial" + GAME + ".h"
@ -11,6 +11,9 @@
#elif GAME == "IW5"
#define FEATURE_IW5
#define HAS_WATER
#elif GAME == "T5"
#define FEATURE_T5
#define HAS_WATER
#elif GAME == "T6"
#define FEATURE_T6
#endif
@ -80,6 +83,8 @@ namespace GAME
GT0,
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_IW5)
LT128,
#elif defined(FEATURE_T5)
GE255,
#endif
GE128
};
@ -90,6 +95,8 @@ namespace GAME
{JsonAlphaTest::GT0, "gt0" },
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_IW5)
{JsonAlphaTest::LT128, "lt128" },
#elif defined(FEATURE_T5)
{JsonAlphaTest::GE255, "ge255" },
#endif
{JsonAlphaTest::GE128, "ge128" }
});
@ -321,7 +328,7 @@ namespace GAME
{TS_2D, "2D" },
{TS_FUNCTION, "function" },
{TS_COLOR_MAP, "colorMap" },
#if defined(FEATURE_IW3) || defined(FEATURE_T6)
#if defined(FEATURE_IW3) || defined(FEATURE_T5) || defined(FEATURE_T6)
{TS_UNUSED_1, "unused1" },
#else
{TS_DETAIL_MAP, "detailMap" },
@ -332,15 +339,17 @@ namespace GAME
{TS_UNUSED_4, "unused4" },
{TS_SPECULAR_MAP, "specularMap" },
{TS_UNUSED_5, "unused5" },
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_IW5)
#ifdef FEATURE_T6
{TS_OCCLUSION_MAP, "occlusionMap" },
#endif
{TS_UNUSED_6, "unused6" },
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_IW5) || defined(FEATURE_T5)
{TS_WATER_MAP, "waterMap" },
#endif
#ifdef FEATURE_IW5
{TS_DISPLACEMENT_MAP, "displacementMap"},
#endif
#elif defined(FEATURE_T6)
{TS_OCCLUSION_MAP, "occlusionMap" },
{TS_UNUSED_6, "unused6" },
#if defined(FEATURE_T5) || defined(FEATURE_T6)
{TS_COLOR0_MAP, "color0Map" },
{TS_COLOR1_MAP, "color1Map" },
{TS_COLOR2_MAP, "color2Map" },
@ -369,7 +378,7 @@ namespace GAME
std::optional<std::string> nameStart;
std::optional<std::string> nameEnd;
TextureSemantic semantic;
#ifdef FEATURE_T6
#if defined(FEATURE_T5) || defined(FEATURE_T6)
bool isMatureContent;
#endif
JsonSamplerState samplerState;
@ -393,7 +402,7 @@ namespace GAME
}
out["semantic"] = in.semantic;
#ifdef FEATURE_T6
#if defined(FEATURE_T5) || defined(FEATURE_T6)
out["isMatureContent"] = in.isMatureContent;
#endif
out["samplerState"] = in.samplerState;
@ -410,7 +419,7 @@ namespace GAME
optional_from_json(in, "nameStart", out.nameStart);
optional_from_json(in, "nameEnd", out.nameEnd);
in.at("semantic").get_to(out.semantic);
#ifdef FEATURE_T6
#if defined(FEATURE_T5) || defined(FEATURE_T6)
in.at("isMatureContent").get_to(out.isMatureContent);
#endif
in.at("samplerState").get_to(out.samplerState);
@ -445,24 +454,28 @@ namespace GAME
{MTL_GAMEFLAG_8, "8" },
{MTL_GAMEFLAG_10, "10" },
{MTL_GAMEFLAG_20, "20" },
#if defined(FEATURE_IW3) || defined(FEATURE_T6)
#if defined(FEATURE_IW3) || defined(FEATURE_T5) || defined(FEATURE_T6)
{MTL_GAMEFLAG_CASTS_SHADOW, "CASTS_SHADOW"},
{MTL_GAMEFLAG_CASTS_SHADOW, "40" },
#else
{MTL_GAMEFLAG_40, "40" },
#endif
{MTL_GAMEFLAG_80, "80" },
#ifdef FEATURE_T6
#if defined(FEATURE_T5) || defined(FEATURE_T6)
{MTL_GAMEFLAG_100, "100" },
{MTL_GAMEFLAG_200, "200" },
#if defined(FEATURE_T6)
{MTL_GAMEFLAG_400, "400" },
{MTL_GAMEFLAG_800, "800" },
{MTL_GAMEFLAG_1000, "1000" },
{MTL_GAMEFLAG_2000, "2000" },
{MTL_GAMEFLAG_4000, "4000" },
#endif
#endif
});
NLOHMANN_JSON_SERIALIZE_ENUM(GfxCameraRegionType, {
#if defined(FEATURE_IW3)
#if defined(FEATURE_IW3) || defined(FEATURE_T5)
{CAMERA_REGION_LIT, "lit" },
{CAMERA_REGION_DECAL, "decal" },
{CAMERA_REGION_EMISSIVE, "emissive" },
@ -492,7 +505,9 @@ namespace GAME
class JsonMaterial
{
public:
#ifdef FEATURE_T6
#ifdef FEATURE_T5
uint8_t maxStreamedMips;
#elif defined(FEATURE_T6)
unsigned layeredSurfaceTypes;
unsigned hashIndex;
unsigned surfaceFlags;
@ -515,7 +530,9 @@ namespace GAME
NLOHMANN_DEFINE_TYPE_EXTENSION(
JsonMaterial,
#ifdef FEATURE_T6
#ifdef FEATURE_T5
maxStreamedMips,
#elif defined(FEATURE_T6)
layeredSurfaceTypes,
hashIndex,
surfaceFlags,

View File

@ -0,0 +1,54 @@
#include "LoaderMaterialT5.h"
#include "Game/T5/Material/JsonMaterialLoaderT5.h"
#include "Game/T5/T5.h"
#include "Material/MaterialCommon.h"
#include <format>
#include <iostream>
using namespace T5;
namespace
{
class MaterialLoader final : public AssetCreator<AssetMaterial>
{
public:
MaterialLoader(MemoryManager& memory, ISearchPath& searchPath)
: m_memory(memory),
m_search_path(searchPath)
{
}
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
{
const auto file = m_search_path.Open(material::GetFileNameForAssetName(assetName));
if (!file.IsOpen())
return AssetCreationResult::NoAction();
auto* material = m_memory.Alloc<Material>();
material->info.name = m_memory.Dup(assetName.c_str());
AssetRegistration<AssetMaterial> registration(assetName, material);
if (!LoadMaterialAsJson(*file.m_stream, *material, m_memory, context, registration))
{
std::cerr << std::format("Failed to load material \"{}\"\n", assetName);
return AssetCreationResult::Failure();
}
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
}
private:
MemoryManager& m_memory;
ISearchPath& m_search_path;
};
} // namespace
namespace T5
{
std::unique_ptr<AssetCreator<AssetMaterial>> CreateMaterialLoader(MemoryManager& memory, ISearchPath& searchPath)
{
return std::make_unique<MaterialLoader>(memory, searchPath);
}
} // namespace T5

View File

@ -0,0 +1,12 @@
#pragma once
#include "Asset/IAssetCreator.h"
#include "Game/T5/T5.h"
#include "Gdt/IGdtQueryable.h"
#include "SearchPath/ISearchPath.h"
#include "Utils/MemoryManager.h"
namespace T5
{
std::unique_ptr<AssetCreator<AssetMaterial>> CreateMaterialLoader(MemoryManager& memory, ISearchPath& searchPath);
} // namespace T5

View File

@ -5,6 +5,7 @@
#include "Game/T5/T5.h"
#include "Game/T5/XModel/LoaderXModelT5.h"
#include "Localize/LoaderLocalizeT5.h"
#include "Material/LoaderMaterialT5.h"
#include "ObjLoading.h"
#include "RawFile/LoaderRawFileT5.h"
#include "StringTable/LoaderStringTableT5.h"
@ -104,7 +105,7 @@ namespace
// collection.AddAssetCreator(std::make_unique<AssetLoaderDestructibleDef>(memory));
// collection.AddAssetCreator(std::make_unique<AssetLoaderXAnim>(memory));
collection.AddAssetCreator(CreateXModelLoader(memory, searchPath, zone));
// collection.AddAssetCreator(std::make_unique<AssetLoaderMaterial>(memory));
collection.AddAssetCreator(CreateMaterialLoader(memory, searchPath));
// collection.AddAssetCreator(std::make_unique<AssetLoaderTechniqueSet>(memory));
// collection.AddAssetCreator(std::make_unique<AssetLoaderImage>(memory));
// collection.AddAssetCreator(std::make_unique<AssetLoaderSoundBank>(memory));

View File

@ -1,4 +1,4 @@
#options GAME (IW3, IW4, IW5, T6)
#options GAME (IW3, IW4, IW5, T5, T6)
#filename "Game/" + GAME + "/Material/JsonMaterialLoader" + GAME + ".cpp"
@ -14,6 +14,10 @@
#define FEATURE_IW5
#define HAS_WATER
#define GAME_LOWER "iw5"
#elif GAME == "T5"
#define FEATURE_T5
#define HAS_WATER
#define GAME_LOWER "t5"
#elif GAME == "T6"
#define FEATURE_T6
#define GAME_LOWER "t6"
@ -29,6 +33,7 @@
#ifdef HAS_WATER
#include "Base64.h"
#endif
#set COMMON_HEADER "\"Game/" + GAME + "/Common" + GAME + ".h\""
#include COMMON_HEADER
#set JSON_HEADER "\"Game/" + GAME + "/Material/JsonMaterial" + GAME + ".h\""
@ -100,7 +105,7 @@ namespace
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_IW5)
static bool CreateGameFlagsFromJson(const JsonMaterial& jMaterial, unsigned char& gameFlags)
#elif defined(FEATURE_T6)
#elif defined(FEATURE_T5) || defined(FEATURE_T6)
static bool CreateGameFlagsFromJson(const JsonMaterial& jMaterial, unsigned& gameFlags)
#endif
{
@ -201,7 +206,7 @@ namespace
CreateSamplerStateFromJson(jTexture.samplerState, textureDef.samplerState);
textureDef.semantic = jTexture.semantic;
#ifdef FEATURE_T6
#if defined(FEATURE_T5) || defined(FEATURE_T6)
textureDef.isMatureContent = jTexture.isMatureContent;
#endif
@ -314,6 +319,12 @@ namespace
structured.alphaTestDisabled = 0;
structured.alphaTest = GFXS_ALPHA_TEST_LT_128;
}
#elif defined(FEATURE_T5)
else if (jStateBitsTableEntry.alphaTest == JsonAlphaTest::GE255)
{
structured.alphaTestDisabled = 0;
structured.alphaTest = GFXS_ALPHA_TEST_GE_255;
}
#endif
else if (jStateBitsTableEntry.alphaTest == JsonAlphaTest::GE128)
{
@ -424,7 +435,9 @@ namespace
material.stateFlags = static_cast<unsigned char>(jMaterial.stateFlags);
material.cameraRegion = jMaterial.cameraRegion;
#ifdef FEATURE_T6
#if defined(FEATURE_T5)
material.maxStreamedMips = jMaterial.maxStreamedMips;
#elif defined(FEATURE_T6)
material.probeMipBits = jMaterial.probeMipBits;
#endif

View File

@ -1,4 +1,4 @@
#options GAME (IW3, IW4, IW5, T6)
#options GAME (IW3, IW4, IW5, T5, T6)
#filename "Game/" + GAME + "/Material/JsonMaterialLoader" + GAME + ".h"

View File

@ -26,5 +26,6 @@ void AssetDumperMaterial::DumpAsset(AssetDumpingContext& context, XAssetInfo<Mat
if (!assetFile)
return;
DumpMaterialAsJson(*assetFile, *asset->Asset(), context);
const auto* material = asset->Asset();
DumpMaterialAsJson(*assetFile, *material, context);
}

View File

@ -0,0 +1,34 @@
#include "DumperMaterialT5.h"
#include "Game/T5/Material/JsonMaterialWriterT5.h"
#include "Game/T5/Material/MaterialConstantZoneStateT5.h"
#include "Material/MaterialCommon.h"
#include <assert.h>
using namespace T5;
void AssetDumperMaterial::DumpPool(AssetDumpingContext& context, AssetPool<Material>* pool)
{
auto* materialConstantState = context.GetZoneAssetDumperState<MaterialConstantZoneState>();
materialConstantState->ExtractNamesFromZone();
AbstractAssetDumper::DumpPool(context, pool);
}
bool AssetDumperMaterial::ShouldDump(XAssetInfo<Material>* asset)
{
return true;
}
void AssetDumperMaterial::DumpAsset(AssetDumpingContext& context, XAssetInfo<Material>* asset)
{
const auto assetFile = context.OpenAssetFile(material::GetFileNameForAssetName(asset->m_name));
if (!assetFile)
return;
const auto* material = asset->Asset();
assert(material->info.gameFlags < 0x400);
DumpMaterialAsJson(*assetFile, *material, context);
}

View File

@ -0,0 +1,17 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/T5/T5.h"
namespace T5
{
class AssetDumperMaterial final : public AbstractAssetDumper<Material>
{
public:
void DumpPool(AssetDumpingContext& context, AssetPool<Material>* pool) override;
protected:
bool ShouldDump(XAssetInfo<Material>* asset) override;
void DumpAsset(AssetDumpingContext& context, XAssetInfo<Material>* asset) override;
};
} // namespace T5

View File

@ -0,0 +1,524 @@
#include "MaterialConstantZoneStateT5.h"
#include "Game/T5/CommonT5.h"
#include "Game/T5/GameAssetPoolT5.h"
#include "Game/T5/GameT5.h"
#include "ObjWriting.h"
namespace T5
{
const char* KNOWN_CONSTANT_NAMES[]{
"AngularVelocityScale",
"AnimSpeed",
"Background",
"BackgroundColor",
"BackgroundNoise",
"BakedLightingIntensity",
"BloodBrightness",
"BloodIntensity",
"BlurAmount",
"CapWidth",
"Char_Size",
"Char_Width",
"Coarseness",
"Color",
"ColorAmount",
"ColorBias",
"Color_Map_Noise",
"Color_Map_Scale",
"Color_Map_Size_Scale",
"DDXScale",
"DDYScale",
"DarkenAmount",
"DarkenPower",
"Detail_Amount",
"Detail_Normal_Tile",
"Diffuse_Normal_Height_Facing",
"Dimensions",
"DispersionAmount",
"Dolly",
"EdgeColor",
"EdgeHarshness",
"EdgeIntensity",
"EdgeMaxDist",
"EdgeMinDist",
"EdgeSize",
"Edge_Color_Multiplier",
"Emissive_Amount",
"EnemiesColor",
"Exposure",
"FPS",
"Fade_Distance",
"Fill_Direction",
"Fill_Direction2",
"FirstFrame",
"FlareIntensity",
"FlareScale",
"FlattenEdges",
"Flicker_Max",
"Flicker_Min",
"Flicker_Seed",
"Flicker_Speed",
"Font_Color",
"Gamma",
"GlossAmount",
"Gloss_Amount",
"Glow_Alt_Color",
"Glow_Color",
"Glow_Falloff",
"GradientColor",
"GradientMax",
"GradientMin",
"Grain_Amount",
"Grain_Color",
"Grid",
"Hardness",
"Heart_Rate_Offset",
"Heart_Rate_Scale",
"Highlight_1_Brightness",
"Highlight_1_Sharpness",
"Highlight_2_Brightness",
"Highlight_2_Sharpness",
"Highlight_2_Size",
"Hightlight_1_Size",
"Holo_Scale",
"LastFrame",
"Layer1Alpha",
"Layer1Depth",
"Layer1Offset",
"Layer1OffsetBobbleDelay",
"Layer1OffsetBobbleSpeedAndSize",
"Layer1Origin",
"Layer1Rotation",
"Layer1Scale",
"Layer1ScaleBobbleDelay",
"Layer1ScaleBobbleSpeedAndSize",
"Layer1Scroll",
"Layer2Alpha",
"Layer2Depth",
"Layer2Offset",
"Layer2OffsetBobbleDelay",
"Layer2OffsetBobbleSpeedAndSize",
"Layer2Origin",
"Layer2Rotation",
"Layer2Scale",
"Layer2ScaleBobbleDelay",
"Layer2ScaleBobbleSpeedAndSize",
"Layer2Scroll",
"Layer3Alpha",
"Layer3Depth",
"Layer3Offset",
"Layer3Origin",
"Layer3Rotation",
"Layer3Scale",
"Layer3Scroll",
"Layer4Alpha",
"Layer4Depth",
"Layer4Offset",
"Layer4Origin",
"Layer4Rotation",
"Layer4Scale",
"Layer4Scroll",
"LineColor",
"LineNoise",
"LineWidth",
"MaxDepth",
"MaxFlickerColor",
"MaxPulseDepth",
"MaxResolution",
"Max_Color",
"Maximum_Distance",
"Midlayer_Depth",
"MinDepth",
"MinFlickerColor",
"MinResolution",
"MinStatic",
"MinVelocityFraction",
"Min_Color",
"Min_Player_Intensity",
"MomentumColor",
"NegativeColor",
"NoisePower",
"Noise_Scale",
"NormalHeightMultiplier",
"Normal_Detail_Height",
"Normal_Detail_Scale",
"Normal_Map_Size_Scale",
"Normal_Variance_Scale",
"NumFrames",
"Outline_Lookup_Scale",
"OverallAmount",
"OverallBrightness",
"Overlay_Color",
"P1",
"P2",
"Padding",
"Player_Color_Multiplier",
"Player_Lookup_Scale",
"PositiveColor",
"Power",
"PulseColor",
"PulseInterval",
"PulseTime",
"Pulse_Color_Multiplier",
"Pulse_Lookup_Scale",
"Radius",
"ReflectionAmount",
"Reflection_Amount",
"Reflection_Blur",
"Reticle_Alt_Color",
"Reticle_Color",
"Row_Chars_",
"Scale",
"ScanlineColor",
"ScanlineIntensity",
"ScanlineOffset",
"ScanlinePower",
"ScanlineSpeed",
"ScatterAmount",
"ScatterSize",
"SceneNoise",
"SparkleBrightness",
"SparkleDensity",
"SparklePower",
"SparkleProbeAmount",
"SparkleScale",
"SparkleSpecAmount",
"SparkleWash",
"SpecGloss_Map_Size_Scale",
"SpecularAmount",
"SpecularColor",
"Specular_Amount",
"Specular_Decay_Threshold",
"Speed",
"StaticAmount",
"StaticLookupSpeed",
"StaticLookupX",
"StaticScale",
"Static_Size",
"Static_amount",
"TearLookupMaxX",
"TearLookupMinX",
"TearLookupSpeed",
"TearMultiplier",
"TearPower",
"Thickness",
"TickMarkColorAndHarshness",
"Tint",
"VelocityScale",
"VignetteMultiplier",
"VignettePower",
"WarpAmount",
"WarpHeight",
"WarpScale",
"WarpSpeed",
"WashOut",
"WashoutMultiply",
"WaterDirection",
"WaterHeight",
"WaterRefraction",
"WaterScale1",
"WaterScale2",
"WaterSpeed1",
"WaterSpeed2",
"Zoom",
"alphaDissolveParms",
"alphaRevealParms",
"alphaRevealParms1",
"alphaRevealParms2",
"alphaRevealParms3",
"alphaRevealParms4",
"clipSpaceLookupOffset",
"clipSpaceLookupScale",
"cloudsFeather",
"cloudsHeights",
"cloudsUVMad1",
"cloudsUVMad2",
"cloudsUVMul1",
"cloudsUVMul2",
"codeMeshArg",
"colorDetailScale",
"colorObjMax",
"colorObjMaxBaseBlend",
"colorObjMin",
"colorObjMinBaseBlend",
"colorTint",
"debugBumpmap",
"debugPerformance",
"detailScale",
"detailScale1",
"detailScale2",
"detailScale3",
"detailScale4",
"distortionScale",
"dofEquationScene",
"dofEquationViewModelAndFarBlur",
"dofLerpBias",
"dofLerpDownBias",
"dofLerpDownScale",
"dofLerpScale",
"dofLerpUpBias",
"dofLerpUpScale",
"dofRowDelta",
"eyeOffsetParms",
"falloffBeginColor",
"falloffEndColor",
"falloffParms",
"featherParms",
"flagParams",
"framebufferRead",
"gameTime",
"hdrAmount",
"inverseTransposeWorldMatrix",
"inverseTransposeWorldViewMatrix",
"inverseWorldMatrix",
"inverseWorldViewMatrix",
"motionblurDirectionAndMagnitude",
"occlusionAmount",
"occlusionAmount1",
"occlusionAmount2",
"occlusionAmount3",
"occlusionAmount4",
"particleCloudColor",
"particleCloudMatrix",
"particleCloudVelWorld",
"resizeParams1",
"resizeParams2",
"scaleRGB",
"scriptVector0",
"scriptVector1",
"scriptVector2",
"scriptVector3",
"scriptVector4",
"scriptVector5",
"scriptVector6",
"scriptVector7",
"skyBoxCloudWeights",
"skyBoxRotationSize",
"skyColorParms",
"spotLightWeight",
"treeCanopyLightingParms",
"treeCanopyScatterColor",
"treeCanopySwayParms",
"ui3dUVSetup0",
"ui3dUVSetup1",
"ui3dUVSetup2",
"ui3dUVSetup3",
"ui3dUVSetup4",
"ui3dUVSetup5",
"uvAnimParms",
"uvScroll",
"viewMatrix",
"weaponParam0",
"weaponParam1",
"weaponParam2",
"weaponParam3",
"weaponParam4",
"weaponParam5",
"weaponParam6",
"weaponParam7",
"weaponParam8",
"weaponParam9",
"worldViewMatrix",
"worldViewProjectionMatrix",
};
const char* KNOWN_TEXTURE_DEF_NAMES[]{
"AddMap",
"Blip_Mask",
"BlockNoise",
"CS_Z_buffer",
"Camo_Detail_Map",
"Color_Map",
"CompassMap",
"Detail_Map",
"Diffuse",
"Diffuse_Map",
"DpadTexture",
"FontTextutre",
"Grain_Map",
"GridTexture",
"GrimeMap",
"Heart_Rate_Image",
"Hologram_Diffuse",
"Image",
"Layer1Map",
"Layer2Map",
"Layer3Map",
"Layer4Map",
"Lookup",
"Lookup2",
"LookupMap",
"Mask",
"Noise",
"Noise_Texture",
"NormalDetailMap",
"Normal_Detail_Map",
"Normal_Map",
"Overlay_Map",
"Reflection_Mask",
"Reveal_Map",
"Rim_Color_Mask",
"Rim_Specular_Mask",
"Rim_Occlusion_Mask",
"Scanline",
"SparkleMap",
"SpecularAndGloss",
"SpecularAndGloss2",
"Specular_Color_Map",
"Specular_Gloss_Map",
"Specular_Map",
"SpotShadowSamplerState",
"SpotShadowState",
"SpriteMap",
"Static",
"StaticMap",
"Static_Noise_Map",
"SunShadowSamplerState",
"SunShadowState",
"Surface_Normal_Map",
"ThermalMapMask",
"Thermal_Gradient",
"Thermal_Map",
"TickMarkMaterial",
"Tile",
"WarpMap",
"WaterNormalMap",
"Weapon_Normal_Map",
"Weapon_Specular_Map",
"Wireframe",
"ZBuffer_Map",
"attenuation",
"attenuationSampler",
"baseLut2D",
"baseLut2DSampler",
"cinematicA",
"cinematicASampler",
"cinematicCb",
"cinematicCbSampler",
"cinematicCr",
"cinematicCrSampler",
"cinematicY",
"cinematicYSampler",
"codeTexture0",
"codeTexture1",
"codeTexture2",
"color",
"colorDetailMap",
"colorDetailMapSampler",
"colorMap",
"colorMap1",
"colorMap2",
"colorMap2D",
"colorMapPostSun",
"colorMapPostSunSampler",
"colorMapSampler",
"colorMapSampler1",
"colorMapSampler2",
"colorSampler",
"detailMap",
"detailMapSampler",
"dlightAttenuation",
"dlightAttenuationSampler",
"floatZ",
"floatZSampler",
"imageSampler",
"lightmapSamplerSecondary",
"lightmapSecondary",
"lut2D",
"lut2DSampler",
"lut3D",
"lut3DSampler",
"missileCam",
"missileCamSampler",
"modelLighting",
"modelLightingSampler",
"normalMap",
"normalMap1",
"normalMap2",
"normalMapSampler",
"normalMapSampler1",
"normalMapSampler2",
"occlusionMap",
"occlusionMapSampler",
"occMap",
"occMapSampler",
"outdoorMap",
"outdoorMapSampler",
"radiantDiffuseMap",
"rawFloatZ",
"rawFloatZSampler",
"reflectionProbe",
"reflectionProbeSampler",
"shadowmapSamplerSpot",
"shadowmapSamplerSun",
"shadowmapSpot",
"shadowmapSun",
"sonarColor",
"sonarColorSampler",
"sonarDepth",
"sonarDepthSampler",
"source",
"specularMap",
"specularMap1",
"specularMap2",
"specularMapSampler",
"specularMapSampler1",
"specularMapSampler2",
"stencil",
"stencilSampler",
"ui3d",
"ui3dSampler",
};
void MaterialConstantZoneState::ExtractNamesFromZoneInternal()
{
for (const auto* zone : IGame::GetGameById(GameId::T6)->GetZones())
{
const auto* assetPools = dynamic_cast<const GameAssetPoolT5*>(zone->m_pools.get());
if (!assetPools)
return;
for (const auto* techniqueSetInfo : *assetPools->m_technique_set)
{
const auto* techniqueSet = techniqueSetInfo->Asset();
for (const auto* technique : techniqueSet->techniques)
{
if (technique)
ExtractNamesFromTechnique(technique);
}
}
}
}
unsigned MaterialConstantZoneState::HashString(const std::string& str)
{
return Common::R_HashString(str.c_str());
}
void MaterialConstantZoneState::ExtractNamesFromTechnique(const MaterialTechnique* technique)
{
if (!ShouldDumpFromStruct(technique))
return;
for (auto passIndex = 0u; passIndex < technique->passCount; passIndex++)
{
const auto& pass = technique->passArray[passIndex];
if (pass.vertexShader && pass.vertexShader->prog.loadDef.program)
ExtractNamesFromShader(pass.vertexShader->prog.loadDef.program, pass.vertexShader->prog.loadDef.programSize);
if (pass.pixelShader && pass.pixelShader->prog.loadDef.program)
ExtractNamesFromShader(pass.pixelShader->prog.loadDef.program, pass.pixelShader->prog.loadDef.programSize);
}
}
void MaterialConstantZoneState::AddStaticKnownNames()
{
for (const auto* knownConstantName : KNOWN_CONSTANT_NAMES)
AddConstantName(knownConstantName);
for (const auto* knownTextureDefName : KNOWN_TEXTURE_DEF_NAMES)
AddTextureDefName(knownTextureDefName);
}
} // namespace T5

View File

@ -0,0 +1,18 @@
#pragma once
#include "Game/T5/T5.h"
#include "Material/AbstractMaterialConstantZoneState.h"
#include <string>
namespace T5
{
class MaterialConstantZoneState final : public AbstractMaterialConstantZoneStateDx11
{
protected:
void ExtractNamesFromZoneInternal() override;
void ExtractNamesFromTechnique(const MaterialTechnique* technique);
void AddStaticKnownNames() override;
unsigned HashString(const std::string& str) override;
};
} // namespace T5

View File

@ -10,6 +10,7 @@
#include "AssetDumpers/AssetDumperWeapon.h"
#include "AssetDumpers/AssetDumperXModel.h"
#include "Game/T5/GameAssetPoolT5.h"
#include "Material/DumperMaterialT5.h"
#include "ObjWriting.h"
using namespace T5;
@ -30,7 +31,7 @@ bool ObjWriter::DumpZone(AssetDumpingContext& context) const
// DUMP_ASSET_POOL(AssetDumperDestructibleDef, m_destructible_def, ASSET_TYPE_DESTRUCTIBLEDEF)
// DUMP_ASSET_POOL(AssetDumperXAnimParts, m_xanim_parts, ASSET_TYPE_XANIMPARTS)
DUMP_ASSET_POOL(AssetDumperXModel, m_xmodel, ASSET_TYPE_XMODEL)
// DUMP_ASSET_POOL(AssetDumperMaterial, m_material, ASSET_TYPE_MATERIAL)
DUMP_ASSET_POOL(AssetDumperMaterial, m_material, ASSET_TYPE_MATERIAL)
// DUMP_ASSET_POOL(AssetDumperTechniqueSet, m_technique_set, ASSET_TYPE_TECHNIQUE_SET)
DUMP_ASSET_POOL(AssetDumperGfxImage, m_image, ASSET_TYPE_IMAGE)
// DUMP_ASSET_POOL(AssetDumperSndBank, m_sound_bank, ASSET_TYPE_SOUND)

View File

@ -4,6 +4,8 @@
#include "Game/T6/Material/MaterialConstantZoneStateT6.h"
#include "Material/MaterialCommon.h"
#include <cassert>
using namespace T6;
void AssetDumperMaterial::DumpPool(AssetDumpingContext& context, AssetPool<Material>* pool)
@ -26,5 +28,7 @@ void AssetDumperMaterial::DumpAsset(AssetDumpingContext& context, XAssetInfo<Mat
if (!assetFile)
return;
DumpMaterialAsJson(*assetFile, *asset->Asset(), context);
const auto* material = asset->Asset();
assert(material->info.gameFlags < 0x8000);
DumpMaterialAsJson(*assetFile, *material, context);
}

View File

@ -1,4 +1,4 @@
#options GAME (IW3, IW4, IW5, T6)
#options GAME (IW3, IW4, IW5, T5, T6)
#filename "Game/" + GAME + "/Material/JsonMaterialWriter" + GAME + ".cpp"
@ -14,6 +14,10 @@
#define FEATURE_IW5
#define HAS_WATER
#define GAME_LOWER "iw5"
#elif GAME == "T5"
#define FEATURE_T5
#define HAS_WATER
#define GAME_LOWER "t5"
#elif GAME == "T6"
#define FEATURE_T6
#define GAME_LOWER "t6"
@ -144,7 +148,7 @@ namespace
}
jTextureDef.semantic = static_cast<TextureSemantic>(textureDef.semantic);
#if defined(FEATURE_T6)
#if defined(FEATURE_T5) || defined(FEATURE_T6)
jTextureDef.isMatureContent = textureDef.isMatureContent;
#endif
@ -224,6 +228,8 @@ namespace
|| structured.alphaTest == GFXS_ALPHA_TEST_GT_0
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_IW5)
|| structured.alphaTest == GFXS_ALPHA_TEST_LT_128
#elif defined(FEATURE_T5)
|| structured.alphaTest == GFXS_ALPHA_TEST_GE_255
#endif
|| structured.alphaTest == GFXS_ALPHA_TEST_GE_128);
if (structured.alphaTestDisabled)
@ -233,6 +239,9 @@ namespace
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_IW5)
else if (structured.alphaTest == GFXS_ALPHA_TEST_LT_128)
jStateBitsTableEntry.alphaTest = JsonAlphaTest::LT128;
#elif defined(FEATURE_T5)
else if (structured.alphaTest == GFXS_ALPHA_TEST_GE_255)
jStateBitsTableEntry.alphaTest = JsonAlphaTest::GE255;
#endif
else if (structured.alphaTest == GFXS_ALPHA_TEST_GE_128)
jStateBitsTableEntry.alphaTest = JsonAlphaTest::GE128;
@ -317,7 +326,9 @@ namespace
jMaterial.stateFlags = material.stateFlags;
jMaterial.cameraRegion = static_cast<GfxCameraRegionType>(material.cameraRegion);
#ifdef FEATURE_T6
#if defined(FEATURE_T5)
jMaterial.maxStreamedMips = material.maxStreamedMips;
#elif defined(FEATURE_T6)
jMaterial.probeMipBits = material.probeMipBits;
#endif

View File

@ -1,4 +1,4 @@
#options GAME (IW3, IW4, IW5, T6)
#options GAME (IW3, IW4, IW5, T5, T6)
#filename "Game/" + GAME + "/Material/JsonMaterialWriter" + GAME + ".h"